【问题标题】:Linq order by booleanLinq 按布尔值排序
【发布时间】:2022-01-31 17:37:56
【问题描述】:

我有一个 linq 查询,我想按 f.bar 排序,它是一个字符串,但我也想先按 f.foo 排序,它是一个布尔字段。就像下面的查询一样。

(from f in foo
orderby f.foo, f.bar
select f)

虽然这样编译它并没有按预期工作。它只是通过 f.bar 命令忽略布尔字段。

我知道我很愚蠢,但是我需要做什么才能获得这种行为?

谢谢

【问题讨论】:

    标签: c# linq


    【解决方案1】:

    这应该可以正常工作 - 它应该首先订购具有 false foo 值的实体,然后是具有 true foo 值的实体。

    这当然适用于 LINQ to Objects - 您实际使用的是哪个 LINQ 提供程序?

    这是一个 LINQ to Objects 示例,确实工作:

    using System;
    using System.Linq;
    
    public static class Test
    {
        public static void Main()
        {
            var data = new[]
            {
                new { x = false, y = "hello" },
                new { x = true, y = "abc" },
                new { x = false, y = "def" },
                new { x = true, y = "world" }
            };
            
            var query = from d in data
                        orderby d.x, d.y
                        select d;
            
            foreach (var result in query)
            {
                Console.WriteLine(result);
            }
        }
        
    }
    

    【讨论】:

    • 史诗般的失败...刚刚意识到这是由于错误,这意味着 f.foo 总是错误的...。很尴尬
    • 正确,false (0) 按升序(默认)排序在 true (1) 之前。
    • @JonSkeet 你会怎么用 lambda 写这个?
    • @Sipo:作为data.OrderBy(d => d.x).ThenBy(d => d.y)
    【解决方案2】:

    只是想这样做,它似乎没有隐含的顺序。为了更明确,我做了以下操作:

    Something.OrderBy(e=>e.SomeFlag ? 0 : 1) 
    

    将某事从真到假排序。

    【讨论】:

    • 比起内置方式,我更喜欢这种方式。主要是因为即使存在对真/假的隐含排序,对于以前没有这样做过的人来说也不是很明显。因此,将来不知道查看代码的人可能会认为它排序为真到假,而实际上它排序为假到真......至少使用此解决方案,代码使您打算以哪种方式排序非常明显。
    • 是的,我喜欢代码中的那个!如果你必须去 msdn 或 stackoverflow 阅读文档来理解代码,那么在我看来它不是很好的代码
    • 对我来说闻起来像魔术数字。我假设每个程序员都应该非常清楚布尔值true 意味着a single bit set to 1,我错了吗?对我来说,true > false 的真相是显而易见的。
    • @Mels 不是幻数。仅用于排序和排序的显式值。值可能是 42 和 69,关键是代码的读者知道其中一个较小,因此将是第一个。代码的读者可能不知道 OrderBy 将以哪种方式放置布尔值 - 将 true 放在首位,或者将 false 放在首位。 true > false 并不广为人知,而 1 > 0 是。
    • 请注意,.OrderBy(e => e.SomeFlag == true) 将等效于 .OrderBy(e => e.SomeFlag),而 .OrderBy(e => e.SomeFlag ? 0 : 1) 等效于 .OrderByDescending(e => e.SomeFlag)。前两种在真之前是假,另外两种在假之前是真。
    【解决方案3】:

    为了更明确地说明所使用的顺序。

    Something.OrderBy(e => e.SomeFlag, new BooleanComparer());
    
    public class BooleanComparer : IComparer<bool>
    {
        public int Compare(bool x, bool y)
        {
            int p = x ? 1 : 0;
            int q = y ? 1 : 0;
            return p - q; 
        }
    }
    

    【讨论】:

    • 这行得通,但只是矫枉过正,而且更难理解。
    【解决方案4】:

    如果您得到 list orderby true ,请尝试以下代码。

    db.member.where(x=>x.id==memberId).OrderBy(x=>!x.IsPrimary?1:0).ToList();
    

    【讨论】:

    • 这绝对不能回答问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-20
    • 2023-03-11
    • 2014-09-06
    • 2012-08-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多