web-dev-qa-db-ja.com

C#LINQ Orderby-true / falseはorderbyにどのように影響しますか?

IDのリストがあるため、LINQの注文を少し勉強していましたが、順番に注文する必要があります。ただし、標準の順序よりも優先する必要がある特定のIDがあります。

このC#コード(テストするために 。NET Fiddle に貼り付けることができます)を考えると、順序付けは必要に応じて機能しますが、なぜ(!)コンテナの演算子は正しい順序を教えてくれますか?

予想される注文出力は(5, 1, 2, 3, 4, 6, 7, 8, 9)。

順序付けに Contains がある場合、trueを返した行に順序付けの優先順位を与えるべきではありませんか?代わりに、falseを返す行に順序付けの優先順位を与えるように見えます。

using System.Linq;
using System;

public class Program
{
  public static void Main()
  {
    var numbersToFilterBy = new [] {5, 11, 20};

    var x = new [] {new XClass(){Id = 1}, new XClass(){Id = 9}, new XClass(){Id = 5}, new XClass(){Id = 3}, new XClass(){Id = 4}, new XClass(){Id = 2}, new XClass(){Id = 6}, new XClass(){Id = 8}, new XClass(){Id = 7}};

    var trueData = (from data in x
                   orderby !numbersToFilterBy.Contains(data.Id), data.Id
                    select data).ToList();

    foreach(var item in trueData){
        Console.WriteLine(item.Id);
  }
}

public class XClass{
    public int Id{get;set;}
  }
}

これが起こる理由についての説明は何ですか?

27
DotNet NF

OrderBy メソッドは、デフォルトで昇順でアイテムをソートします。ここで、ブール値の数値表現が次のとおりであると仮定します。

  • false = 0
  • true = 1

false値は自然に最初に来ます。順序を逆にする場合は、descendingキーワードを使用します。

var trueData = (from data in x
               orderby numbersToFilterBy.Contains(data.Id) descending, data.Id
                select data).ToList();
43

基本的に、falsetrueより前です。それらをfalse = 0、true = 1と考えてください。これは、 bool.CompareTo(bool)のドキュメント と一致しています。

「真」の値を最初に優先させる場合は、代わりにOrderByDescendingを使用します。

23
Jon Skeet

順序は優先度ではなく、通常値についてです。ブール値に対して昇順を実行しており、falseの順序値は、そのコンテキストでtrueよりも低くなっています。

7
mirichan

_List<bool>_の例でこれを説明しましょう。次のスニペットを検討してください。

_List<bool> BoolList = new List<bool>() { true, false, false, true };
var opList = BoolList.OrderBy(x => x).ToList();
_

最後に、opListの値はfalsefalsetruetrueになります。これは、OrderByを適用するときにfalseが最初に来ることを意味しますブール値のリスト。これは、falseは_0_と見なされ、trueは_1_と見なされるためです。

あなたの場合、リストは最初にorderby !numbersToFilterBy.Contains(data.Id)に基づいて_5,1,9,3,4,2,6,8,7_としてソートされ、次に_data.Id_によって正確な結果が_5, 1, 2, 3, 4, 6, 7, 8, 9_として得られます。

OrderByから_!_を削除すると、_1,9,3,4,2,6,8,7,5_の条件が真であるため、_5_のような最初のソート結果が得られます。したがって、順序の最後になります。

4