web-dev-qa-db-fra.com

C # LINQ Orderby - Comment true / false affecte-t-il orderby?

J'étudiais un peu la commande LINQ car j'ai une liste d'ID et je dois les commander séquentiellement. Cependant, certains identifiants doivent avoir la priorité sur la commande standard.

Étant donné ce code C # (qui peut être collé dans . Fiddle NET pour tester) l'ordre fonctionne comme j'en ai besoin, mais je ne comprends pas pourquoi un pas (!) l'opérateur sur un conteneur me donne la commande correcte?

Ma sortie de commande attendue est (5, 1, 2, 3, 4, 6, 7, 8, 9).

Si j'ai un Contains dans ma commande, ne devrait-il pas donner la priorité de commande aux lignes qui ont renvoyé true? Au lieu de cela, il semble donner la priorité de classement aux lignes qui renvoient 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;}
  }
}

Quelle est l'explication de pourquoi cela se produit?

27
DotNet NF

La méthode OrderBy triera les éléments par ordre croissant par défaut . Maintenant, étant donné que la représentation numérique d'un booléen est:

  • false = 0
  • true = 1

false les valeurs viendront naturellement en premier. Si vous souhaitez inverser l'ordre, utilisez simplement le mot clé descending:

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

Fondamentalement, false est antérieur à true... pensez-y comme faux = 0, vrai = 1. Ceci est conforme à la documentation pour bool.CompareTo(bool) .

Si vous souhaitez prioriser les "vraies" valeurs au début, utilisez simplement OrderByDescending à la place.

23
Jon Skeet

La commande ne concerne pas priorité - elle concerne valeur ordinale. Vous effectuez un ordre croissant par rapport à une valeur booléenne et false a une valeur ordinale inférieure à true dans ce contexte.

7
mirichan

Permettez-moi d'expliquer cela avec un exemple de List<bool>. Considérez l'extrait de code suivant:

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

enfin, le opList aura les valeurs comme false, false, true, true ce qui signifie false en premier lorsque nous appliquons OrderBy sur une liste de valeurs booléennes. En effet, false est considéré comme 0 Et true sera 1.

Dans votre cas, la liste est d'abord triée en 5,1,9,3,4,2,6,8,7 Sur la base de orderby !numbersToFilterBy.Contains(data.Id) puis par data.Id Vous donnera le résultat exact sous la forme 5, 1, 2, 3, 4, 6, 7, 8, 9.

Si vous supprimez le ! Du OrderBy, il vous donne le premier résultat de tri comme 1,9,3,4,2,6,8,7,5 Puisque la condition est vraie pour 5 Donc il viendra en dernier la commande.

4
sujith karivelil