2013-08-13 5 views
5

In C# habe ich einen Objekttyp 'A', der eine Liste der Schlüsselwertpaare enthält.Erstellen einer Liste in C#

Die Schlüsselwertpaare sind eine Kategorie- und eine Werteschlange.

Um Objekttyp A zu instanziiert, würde ich folgendes tun:

List<KeyValuePair> keyValuePairs = new List<KeyValuePair>(); 
keyValuePairs.Add(new KeyValuePair<"Country", "U.S.A">()); 
keyValuePairs.Add(new KeyValuePair<"Name", "Mo">()); 
keyValuePairs.Add(new KeyValuePair<"Age", "33">()); 

A a = new A(keyValuePairs); 

Schließlich habe ich eine Liste von A-Objekttypen haben und ich möchte die Liste bearbeiten, so dass ich nur eindeutige Werte erhalten und ich basiere es nur auf den Ländernamen. Deshalb möchte ich, dass die Liste auf nur ein "Land", "USA" reduziert wird, auch wenn es mehr als einmal erscheint.

Ich suchte in der Linq Distinct, aber es tut nicht, was ich will, weil es ich keine Parameter definieren kann und weil es nicht in der Lage, zwei gleichwertige Objekte des Typs A zu fangen scheint. Ich weiß dass ich die "Equals" -Methode überschreiben kann, aber es löst immer noch nicht mein Problem, das darin besteht, die Liste basierend auf EINEM der Schlüsselwertpaare zu unterscheiden.

+3

Können wir den 'A' Konstruktor sehen? –

+0

Verwenden GroupBy stattdessen ... –

+0

Wenn Sie mehrere "Land" aber mit unterschiedlichen Werten haben, ist das erlaubt? –

Antwort

2

erweitern auf Karl Anderson Vorschlag der Verwendung von morelinq, wenn Sie sind nicht in der Lage (oder nicht wollen) für Ihr Projekt zu einem anderen dll Link, implementiert ich mich diese vor einer Weile:

public static IEnumerable<T> DistinctBy<T, U>(this IEnumerable<T> source, Func<T, U>selector) 
{ 
    var contained = new Dictionary<U, bool>(); 
    foreach (var elem in source) 
    { 
     U selected = selector(elem); 
     bool has; 
     if (!contained.TryGetValue(selected, out has)) 
     { 
      contained[selected] = true; 
      yield return elem; 
     } 
    } 
} 

wie folgt verwendet:

collection.DistinctBy(elem => elem.Property); 

In Versionen von .NET, die es unterstützen, können Sie eine HashSet<T> anstelle eines Dictionary<T, Bool> verwenden, da wir nicht wirklich egal, was der Wert so viel wie, dass es schon gehasht wurde.

1

Sie müssen zuerst die eindeutige Eigenschaft wählen:

Da es sich in einer Liste eine Liste ist, können Sie die Select verwenden. Die SelectMany wird die Ergebnisse von Subselektionen zusammenfassen.

List<A> listOfA = new List<A>(); 

listOfA.SelectMany(a => a.KeyValuePairs 
    .Where(keyValue => keyValue.Key == "Country") 
     .Select(keyValue => keyValue.Value)) 
      .Distinct(); 

Das sollte es sein. Es wählt alle Werte aus, bei denen der Schlüssel "Land" ist, und fasst die Listen zusammen. Abschließend wird es das Land unterscheiden. Da die Eigenschaft KeyValuePairs der Klasse A mindestens ein IEnumerable < KeyValuePair < string, string >>

1

Schauen Sie sich die DistinctBy Syntax in der morelinq project.

A a = new A(keyValuePairs); 

a = a.DistinctBy(k => new { k.Key, k.Value }).ToList(); 
0

Sie können die Anweisung groupby verwenden. Von hier aus können Sie all kind off kühlen stuf tun

listOfA.GroupBy(i=>i.Value) 

Sie den Wert GROUPBY und dann alle Schlüssel oder andere nützliche etwas Summe

1
var result = keyValuePairs.GroupBy(x => x.Key) 
          .SelectMany(g => g.Key == "Country" ? g.Distinct() : g);