ブール値によるLinq順序


111

文字列であるf.barで並べ替えるlinqクエリがありますが、最初にブールフィールドであるf.fooで並べ替えたいです。以下のクエリのように。

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

これはコンパイルされますが、期待どおりに動作しません。ブール値フィールドを無視してf.barで注文するだけです。

私は知っているふざけていますが、この振る舞いをするために何をする必要がありますか?

ありがとう

回答:


175

それはうまくいくはずです-それはfalse最初にfoo値を持つエンティティを順番に並べ、次にfoo値を持つエンティティを並べるべきtrueです。

それは確かにLINQ to Objectsで機能します-どのLINQプロバイダーを実際に使用していますか?

ここではオブジェクトの例にLINQだ仕事は:

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);
        }
    }

}

51
エピックは失敗しました... f.fooが常にfalseであることを意味するバグが原因であることに気づきました...とても恥ずかしい
mat-mcloughlin

5
正解です。false(0)はtrue(1)の前に昇順(デフォルト)でソートされています。
シルクファイア2017

列2で列1をtrueの数でグループ化するにはどうすればよいですか?
Oracular Man 2018

2
@OracularMan:詳細な例を使って新しい質問をすることをお勧めします。
ジョンスキート2018年

1
@Sipo:Asdata.OrderBy(d => d.x).ThenBy(d => d.y)
Jon Skeet

119

これを実行したかっただけで、暗黙の順序付けがないもののようです。より明確にするために、次のことを行いました。

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

何かを真から偽にソートする。


27
私は組み込みの方法よりもこのようにしています。主な理由は、true / falseの暗黙の順序付けがあったとしても、それを以前に行ったことがない人には、それが本当に明白ではないからです。したがって、将来コードを見るのを知らない人は、実際にfalseからtrueにソートされるときに、trueからfalseにソートされると考える可能性があります...
Robert Noack 2013

2
はい、コードでそれが好きです!コードを理解するためにドキュメントを読むためにmsdnまたはstackoverflowに行く必要がある場合、それは私の意見では素晴らしいコードではありません
JonnyRaa

2
私には魔法の数字のようなにおいがします。すべてのプログラマーが本質的にブール値がtrue意味することを非常によく知っているべきだと仮定するのは間違っていa single bit set to 1ますか?私にとって、の真実はtrue > false可能な限り明白です。
Mels 14

4
@メルはマジックナンバーではありません。ソートおよびソートのみに使用される明示的な値。値は42と69の可能性があります。ポイントは、コードの読者がそれらの1つが小さいことを知っているためです。コードの読者は、OrderByがブール値を配置する方法をおそらく認識していません-最初にtrueになるか、最初にfalseになります。true > falseは広く知られているわけではありませんが、知られてい1 > 0ます。
Dan F 14

9
.OrderBy(e => e.SomeFlag == true)と同等になる.OrderBy(e => e.SomeFlag)のに対し、.OrderBy(e => e.SomeFlag ? 0 : 1)同等です.OrderByDescending(e => e.SomeFlag)。最初の2つはtrueの前にfalseをソートし、残りの2つはfalseの前にtrueをソートします。
EriF89 2016年

0

リストorderby trueを取得する場合は、次のコードを試してください。

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

0

使用されている順序をより明確にするため。

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; 
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.