从键/值对中提取唯一键,并将值分组到数组中

时间:2009-07-15 13:10:37

标签: c# arrays

假设我有一个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"

实现这一目标的最简单方法是什么?

5 个答案:

答案 0 :(得分: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 :(得分:1)

可能使用Dictionary&lt; string,List&lt; string&gt;&gt;你可以做点什么

for (var kv in mylistofnamed) {
   if (!dict.ContainsKey(kv.Key))
      dict[kv.Key] = new List<string>();
   dict[kv.Key].Add(kv.Value);
}

答案 2 :(得分:1)

如果您只需要一个只读集合,那么Lookup就可以完成这项工作,就像Meta-Knight's answer一样。

如果您需要在初始创建/填充后修改集合,那么您可能需要Dictionary<string, List<string>>之类的内容。您可以使用LINQ:

从原始列表中创建和填充此类字典
var dict = list
    .GroupBy(x => x.Name)
    .ToDictionary(x => x.Key, y => y.Select(z => z.Value).ToList()); 

答案 3 :(得分:0)

一种方法是使用字典:

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

HashTable可以使用唯一键执行您所需的操作。但是,您必须提供List作为值,因为您将为每个键存储多个值。

这是另一个简单的例子:

http://dotnetperls.com/hashtable-keys

您需要遍历列表中的每个KeyValuePair,以通过将名称存储为键并将值存储为值来填充HashTable。因为您可能有一个指向多个值的名称,所以您需要将HashTable中的值设置为列表。

检查HashTable中是否存在名称,如果不存在,则为该名称创建一个新列表并将值添加到列表中。如果密钥已存在,则访问HashTable中的该元素,并将新值添加到映射到密钥的列表中。

答案 4 :(得分:0)

所有实现IDictionary接口或通用IDictionary接口的类都会对Keys强制执行唯一性检查。您可以使用任何类,但我承认我对Generic Dictionary<TKey, TValue>类的偏好。

添加值时,您只需检查Dictionary对象是否已包含提供的Key。如果没有,那么您可以将该项添加到词典中。