Извлечение уникальных ключей из пар ключ / значение и группирование значений в массив

2

Скажем, у меня есть List<NameValuePair>, где NameValuePair - это простой объект, у которого есть свойство Name и свойство Value, обе строки.

Список заполняется такими значениями:

name = "name1", value = "value1"
name = "name1", value = "value2"
name = "name2", value = "value3"
name = "name3", value = "value4"

Обратите внимание, что есть два экземпляра ключа "name1". Может быть любое количество ключей (так как это список).

Я хочу превратить этот список в новый список, который имеет только уникальные ключи и группирует любые значения с тем же именем ключа, что и массив/список этого ключа.

Итак, выше должно быть:

name = "name1", value = "value1", "value2" // value is a string array or list
name = "name2", value = "value3"
name = "name3", value = "value4"

Каков самый простой способ сделать это?

Теги:
arrays

5 ответов

1
Лучший ответ

Может быть, с словарем < string, List <string → > вы могли бы сделать что-то вроде


for (var kv in mylistofnamed) {
   if (!dict.ContainsKey(kv.Key))
      dict[kv.Key] = new List<string>();
   dict[kv.Key].Add(kv.Value);
}
  • 0
    Это сработало хорошо. Просто для информации, чтобы обработать словарь после, мне пришлось использовать foreach KeyValuePair: foreach (KeyValuePair <string, List <string >> kvp in dict) {Console.WriteLine ("key" + dict.Key); Console.WriteLine («Значение» + dict.Value); }
7

Самый простой способ - ILookup, который по существу похож на словарь, но может иметь более одного значения для каждого ключа.

Вы можете сделать что-то вроде этого, чтобы создать свой поиск:

var lookup = list.ToLookup(pair => pair.name, 
                           pair => pair.value);

Затем вы можете напечатать пары имя/значение, как это:

foreach (var nameGroup in lookup)
{
    var name = nameGroup.Key;
    foreach (string value in nameGroup)
        Console.WriteLine("Name: {0}, Value: {1}", name, value);
}
1

Если вам нужна только коллекция только для чтения, то Lookup будет делать трюк, как в Ответ на Мета-Найт.

Если вам нужно изменить коллекцию после ее первоначального создания/совокупности, вам, вероятно, понадобится что-то вроде Dictionary<string, List<string>>. Вы можете создать и заполнить такой словарь из своего исходного списка с помощью LINQ:

var dict = list
    .GroupBy(x => x.Name)
    .ToDictionary(x => x.Key, y => y.Select(z => z.Value).ToList()); 
0

Один из способов - со словарем:

http://arcanecode.com/2007/03/05/dictionaries-in-c-the-hashtable/

HashTable может делать то, что вам нужно, с помощью уникальных ключей. Однако вам нужно будет предоставить список как значение, так как вы будете хранить несколько значений для каждой клавиши.

Вот еще один простой пример:

http://dotnetperls.com/hashtable-keys

Вам потребуется выполнить итерацию по каждому KeyValuePair в вашем списке, чтобы заполнить HashTable, сохранив имя в качестве ключа и значения в качестве значения. Поскольку у вас может быть имя, указывающее на несколько значений, вам понадобятся ваши значения в HashTable для списков.

Проверьте наличие имени в HashTable, если оно не существует, создайте новый список для этого имени и добавьте значение в список. Если ключ уже существует, обратитесь к этому элементу в HashTable и добавьте новое значение в список, который сопоставляется с ключом.

0

Все классы, реализующие интерфейс IDictionary или интерфейс Generic IDictionary, обеспечивают проверку уникальности ключей. Вы можете использовать любой из классов, хотя я признаю свое предпочтение классу Generic Dictionary<TKey, TValue>.

При добавлении значений вы можете просто проверить, содержит ли объект Dictionary уже указанный ключ. Если нет, вы можете добавить элемент в словарь.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню