【问题标题】:LINQ: Nested Sorting / Ordering with Boolean ValuesLINQ:使用布尔值进行嵌套排序/排序
【发布时间】:2018-02-14 09:48:23
【问题描述】:

鉴于以下情况:

public class Data {
    public bool Value1 { get; set; }
    public bool Value2 { get; set; }
    public int Value3 { get; set; }
}

var list = new List<Data> {
    new Data { Value1 = true, Value2 = false, Value3 = 5}, // d1
    new Data { Value1 = true, Value2 = true, Value3 = 10}, // d2
    new Data { Value1 = false, Value2 = false, Value3 = 20}, // d3
    new Data { Value1 = false, Value2 = true, Value3 = 30}, // d4
    new Data { Value1 = false, Value2 = false, Value3 = 15} // d5
};

var orderedList = list.OrderByDescending(d => d.Value1).ThenByDescending(d => d.Value2).ThenBy(d => d.Value3);

我想要实现的是:d1 - d2 - d4 - d5 - d3

orderedList中的实际结果是:d2 - d1 - d4 - d5 - d3

这是因为d2Value2 Value1true,所以这可能是有道理的。尽管如此,在这个用例中,我并不关心Value1Value2true。我想实现我所拥有的

  • 首先是Value1为真的所有对象,在那些由 Value3
  • 第二个Value2为真的所有对象,在那些 由Value3订购
  • 最后剩下的,由Value3订购

有没有可能做到这一点?

【问题讨论】:

  • 一切皆有可能,试图理解问题被证明是一个问题

标签: c# linq sorting


【解决方案1】:
var orderedList = list.OrderByDescending(d => d.Value1).
    ThenByDescending(d => d.Value1 || d.Value2).
    ThenBy(d => d.Value3);

在第二个表达式中,我使用了 Value1 和 Value2 的组合。如果 Value1 为 true,则结果将始终为 true,无论 Value2 为何,因此“跳过”对结果进行排序。而如果 Value1 是 false,它将完全取决于 Value2。

【讨论】:

  • 这个答案可以做一个解释,这样它就清晰简洁了。
  • @Digitalsa1nt 是的。虽然它很简单,但我添加了一些关于它的作用的解释。
  • 谢谢,它只会提高您的回答质量,像这样的好答案值得付出额外的努力。
【解决方案2】:

以下代码可以帮助您入门。您有三个规则,编码在代码的前三行。

var firstBit = list.Where(z => z.Value1).OrderBy(z => z.Value3);
var secondBit = list.Where(z => !z.Value1 && z.Value2).OrderBy(z => z.Value3);
var last = list.Where(z => !z.Value1 && !z.Value2).OrderBy(z => z.Value3);

var final = firstBit.Concat(secondBit).Concat(last);

Console.WriteLine(string.Join(",", final.Select(z => z.Value3)));

【讨论】:

  • 这个顺便说一句也有效 - 不过@STDMP 的解决方案对我来说更简单
【解决方案3】:

你可以试试下面的

根据评论更新代码。

var orderedVal1 = list.Where(item=>item.Value1==true).OrderBy(d => d.Value3);
var orderedVal2 = list.Where(item=>item.Value1==false && item.Value2==true).OrderBy(d => d.Value3);
var orderedVal3 = list.Where(item=>item.Value1==false && item.Value2 ==false).OrderBy(d => d.Value3);

var orderedList = orederedval1.Concat(orderedVal2).Concat(orderedVal3);

【讨论】:

  • 我们不应该改变orderedVal3来检查value1和value2是否都是false吗?
  • @Zulatin - 更新了代码。此外,对于 orderedVal2 应该只考虑 Value1 为假。否则将为具有 true 的 val1 和 val2 创建重复项。
  • 使用多个列表和Concat 是一种糟糕的方式。
  • 作为 mjwills 的回答从纯粹的功能角度来看也是有效的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-02-22
  • 1970-01-01
  • 1970-01-01
  • 2012-08-10
  • 1970-01-01
  • 2011-04-02
  • 1970-01-01
相关资源
最近更新 更多