2013-08-13 38 views
5

W języku C#, mam typ obiektu "A", który zawiera listę par wartości klucza.Tworzenie listy różnych w C#

Pary wartości klucza to ciąg kategorii i ciąg wartości.

Aby instancję typu Object, musiałbym wykonać następujące czynności:

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

końcu będę mieć listę A typów obiektów i chcę manipulować listę tak, że mogę dostać tylko unikatowe wartości i opieram go tylko na nazwie kraju. Dlatego chcę, aby lista była ograniczona do jednego "kraju", "USA", nawet jeśli pojawia się więcej niż raz.

Szukałem w Linq Distinct, ale nie robi to, co chcę, ponieważ nie mogę zdefiniować żadnych parametrów i ponieważ nie wydaje się być w stanie złapać dwa równoważne obiekty typu A. Wiem że mogę przesłonić metodę "Equals", ale nadal nie rozwiązuje ona mojego problemu, który polega na uczynieniu listy odrębnej na podstawie JEDNEJ z par wartości klucza.

+3

Czy widzimy konstruktora 'A'? –

+0

Użyj GroupBy zamiast ... –

+0

Jeśli masz wiele "Kraj", ale z różnymi wartościami, czy to dozwolone? –

Odpowiedz

2

rozszerzyć na sugestię Karla Andersona korzystania morelinq, jeśli jesteś w stanie (lub nie chcą) link do innej biblioteki dll do projektu, I wdrożone to się chwilę temu:

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

wykorzystane w następujący sposób:

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

W wersjach .NET, który go obsługuje, można użyć HashSet<T> zamiast Dictionary<T, Bool>, ponieważ tak naprawdę nie obchodzi, co wartość jest tak dużo, jak to już zostało zakodowane.

1

Musisz najpierw wybierz odrębną własność:

Ponieważ jest to lista wewnątrz listy, można użyć SelectMany. SelectMany będzie konkatować wyniki podsekcji.

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

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

To powinno być to. Wybrane zostaną wszystkie wartości, w których kluczem jest "Kraj" i łączenie list. Finał będzie wyróżniał kraj. Biorąc pod uwagę, że KeyValuePairs właściwości klasy A jest o co najmniej IEnumerable < KeyValuePair < ciąg, ciąg >>

1

Wyjazd składnia w morelinq projectDistinctBy.

A a = new A(keyValuePairs); 

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

Możesz użyć instrukcji groupby. Stąd można zrobić wszelkiego rodzaju off fajne stuf

listOfA.GroupBy(i=>i.Value) 

Można GroupBy wartość, a następnie sumują wszystkie klucze lub coś innego przydatnych

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