2013-08-13 4 views
5

В C# у меня есть тип объекта 'A', который содержит список пар значений ключа.Создание списка, отличного от C#

Пара ключей значений представляет собой строку категории и строку значений.

Чтобы создать экземпляр объекта типа А, я должен был бы сделать следующее:

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

В конце концов, у меня будет список из типов объектов, и я хочу, чтобы манипулировать список, так что я только получить уникальные значения и я основываю его только на названии страны. Поэтому я хочу, чтобы список был сокращен, чтобы иметь только ОДИН «Страна», «U.S.A», даже если он появляется более одного раза.

Я изучал linq Distinct, но он не делает то, что я хочу, потому что я не могу определить какие-либо параметры и потому что он, похоже, не способен поймать два эквивалентных объекта типа A. Я знаю что я могу переопределить метод «Равно», но он по-прежнему не решает мою проблему, которая заключается в том, чтобы сделать список разным на основе ОДНОЙ из пар значений ключа.

+3

Можно ли увидеть конструктор 'A'? –

+0

Используйте GroupBy вместо этого ... –

+0

Если у вас несколько «Страна», но с разными значениями, разрешено? –

ответ

2

Для расширения по предложению Карла Андерсона использования morelinq, если вы не можете (или не хотите) ссылку на другую библиотеку DLL для проекта, я осуществил это сам некоторое время назад:

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

использовано следующим образом:

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

В версиях .NET, которые поддерживают его, вы можете использовать HashSet<T> вместо Dictionary<T, Bool>, так как мы на самом деле не волнует, что значение настолько, что он уже хешированы.

1

Вы должны выбрать отчетливое свойство первого:

Поскольку это список внутри списка, вы можете использовать SelectMany. SelectMany выполнит результаты подвыборки.

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

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

Это должно быть все. Он выберет все значения, где ключ - «Страна», и составьте списки. Финал будет отличаться от страны. Учитывая, что свойство KeyValuePairs из класса А, по меньшей мере, IEnumerable < < KeyValuePair строка, строка >>

1

Ознакомьтесь DistinctBy синтаксис в morelinq project.

A a = new A(keyValuePairs); 

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

Вы можете использовать оператор groupby. Отсюда вы можете сделать все доброе от прохладное Stuf

listOfA.GroupBy(i=>i.Value) 

Вы можете GroupBy значение, а затем просуммировать все ключи или что-то другое ПОЛЕЗНЫЕ

1
var result = keyValuePairs.GroupBy(x => x.Key) 
          .SelectMany(g => g.Key == "Country" ? g.Distinct() : g); 
Смежные вопросы