2009-08-14 8 views
0

Pour simplifier le scénario, supposons que nous ayons une liste de propriétés People with FirstName et LastName.Ajouter une propriété incrémentée à IEnumerable par groupe à l'aide de LINQ

Nos données ressemble à ceci:

Bob Smith 
Jane Smith 
Todd Grover 
Larry Lewis 
Jill Lewis 
Frank Lewis 

La première étape serait d'ajouter une propriété entière qui s'incrémente pour chaque élément:

Bob Smith 1 
Jane Smith 2 
Todd Grover 3 
Larry Lewis 4 
Jill Lewis 5 
Frank Lewis 6 

Idéalement, je voudrais rétablir la compteur pour chaque nouveau groupe pour atteindre ceci:

Bob Smith 1 
Jane Smith 2 
Todd Grover 1 
Larry Lewis 1 
Jill Lewis 2 
Frank Lewis 3 

Peut-être que LINQ n'est pas approprié. Il semble que LINQ devrait être capable de le faire avec élégance.

+0

c'est la première fois que je sais quelque chose à faire en langage SQL, mais pas en C# (lire "pas aussi rapidement en utilisant Linq") – nawfal

Répondre

5

Si vous venez voulez un compteur qui incrémente avec chaque élément:

var query = people 
    .Select((x, i) => new { x.FirstName, x.LastName, Index = i + 1 }); 

Ou si vous voulez réinitialiser le compteur pour chaque groupe, regroupés par LastName:

var query = people 
    .GroupBy(x => x.LastName) 
    .Select 
    (
     x => x.Select((y, i) => new { y.FirstName, y.LastName, Index = i + 1 }) 
    ) 
    .SelectMany(x => x); 

Et pour afficher rapidement les résultats de la requête:

foreach (var item in query) 
{ 
    Console.WriteLine(item.FirstName + "\t" + item.LastName + "\t" + item.Index); 
} 
1

Si l'on suppose il y a une propriété entière déjà sur le type d'enregistrement, et la collection est déjà triée, vous pouvez abuser des agrégats (c.-à-Fold gauche), quelque chose comme ça

collection.Aggregate((old, next) => { if (namesDiffer(old, next)) next.Index = 1 else next.Index = old.Index +1; return next;}, aRecordWithEmptyName); 

EDIT - retour fixe valeur; les doigts avaient été sur le pilote automatique.

2

Vous pouvez utiliser la deuxième surcharge de la méthode Select, qui intègre un paramètre d'index est passé à l'expression lambda, par exemple:

var people = new [] { 
    new { FirstName = "Bob", LastName = "Smith"}, 
    new { FirstName = "Jane", LastName = "Smith"}, 
    new { FirstName = "Todd", LastName = "Grover"}, 
    new { FirstName = "Larry", LastName = "Lewis"}, 
    new { FirstName = "Jill", LastName = "Lewis"}, 
    new { FirstName = "Frank", LastName = "Lewis"}, 
}.ToList(); 

people.Select((p, index) => new { 
            FirstName = p.FirstName, 
            LastName = p.LastName, 
            Index = index 
           } 
      ); 

Résultat:

select-index

Questions connexes