我有一本看起来像这样的字典:
Dictionary<string, List<string>> dict = new Dictionary<string, List<string>>()
{
{"a" , new List<string> { "Red","Yellow"} },
{"b" , new List<string> { "Blue","Red"} },
{"c" , new List<string> { "Green","Orange"} },
{"d" , new List<string> { "Black","Green"} },
};
我需要从dict
作为字典输出,其中List<string>
中的公用值应该是键,而值应该是键列表。
例如:
Red: [a,b]
Green: [c,d]
我不知道如何使用 list
中的 dictionary
作为 TValue
解决此问题强>。
请解释一下如何在字典中处理列表。
答案 0 :(得分:5)
您可以使用SelectMany
修饰字典,并获得看起来像这样的普通列表
"a" - "Red"
"a" - "Yellow"
"b" - "Blue"
"b" = "Red"
// and so on
然后按值分组并从这些分组中构建新字典。尝试以下代码:
var commonValues = dict.SelectMany(kv => kv.Value.Select(v => new {key = kv.Key, value = v}))
.GroupBy(x => x.value)
.Where(g => g.Count() > 1)
.ToDictionary(g => g.Key, g => g.Select(x => x.key).ToList());
答案 1 :(得分:3)
很多循环...遍历字典,然后遍历列表中的每个值。
var result = new Dictionary<string, List<string>>();
// Loop through each key/value pair in the dictionary
foreach (var kvp in dict)
{
// kvp.Key is the key ("a", "b", etc)
// kvp.Value is the list of values ("Red", "Yellow", etc)
// Loop through each of the values
foreach (var value in kvp.Value)
{
// See if our results dictionary already has an entry for this
// value. If so, grab the corresponding list of keys. If not,
// create a new list of keys and insert it.
if (!result.TryGetValue(value, out var list))
{
list = new List<string>();
result.Add(value, list);
}
// Add our key to this list of keys
list.Add(kvp.Key);
}
}
如果您要通过一项包含多个项目的条目进行过滤,则可以执行以下操作:
result = result.Where(x => x.Value.Count > 1).ToDictionary(x => x.Key, x => x.Value);
或者,您可以避免循环并改用Linq:
// Flatten the dictionary into a set of tuples
// e.g. (a, Red), (a, Yellow), (b, Blue), (b, Red), etc
var result = dict.SelectMany(kvp => kvp.Value.Select(color => (key: kvp.Key, color)))
// Group by the value, taking the color as the elements of the group
// e.g. (Red, (a, b)), (Yellow, (a)), etc
.GroupBy(item => item.color, item => item.key)
// Filter to the ones with more than one item
.Where(group => group.Count() > 1)
// Turn it into a dictionary, taking the key of the grouping
// (Red, Green, etc), as the dictionary key
.ToDictionary(group => group.Key, group => group.ToList());
您还可以使用linq查询语法,该语法稍长一些,但避免了SelectMany
周围的混乱:
var result =
(
from kvp in dict
from color in kvp.Value
group kvp.Key by color into grp
where grp.Count() > 1
select grp
).ToDictionary(grp => grp.Key, grp => grp.ToList());