假设我有一个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"
实现这一目标的最简单方法是什么?
答案 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。如果没有,那么您可以将该项添加到词典中。