请帮助我们尽量减少以下代码: 有一个包含字典属性的类:
class Foo
{
public int Field { get; set; }
public Dictionary<int, bool> dic { get; set; }
}
还有一个Foo实例列表。我想从所有类实例中得到统一字典:
...
var items = new List<Foo>
{
new Foo {Field = 1, Dic = new Dictionary<int, bool> {{1, true}, {2, false}}},
new Foo {Field = 2, Dic = new Dictionary<int, bool> {{3, true}, {2, false}}}
};
var result = new Dictionary<int, bool>();
foreach (var dics in items.Select(x => x.Dic))
foreach (var pair in dics)
if (!result.ContainsKey(pair.Key))
result.Add(pair.Key, pair.Value);
// testing output
foreach (var pair in result)
Console.WriteLine("{0}, {1}", pair.Key, pair.Value);
使用纯LINQ方法可以做到这一点吗? 先感谢您!
答案 0 :(得分:6)
您可以使用SelectMany
来抓取并展平内部词典元素:
var result = items.SelectMany(f => f.Dic)
.GroupBy(pair => pair.Key)
.ToDictionary(g => g.Key, g => g.First().Value);
编辑:如果您感到勇敢,可以通过从Jon Skeet的DistinctBy项目中选择morelinq方法来进一步改进。从本质上讲,GroupBy
步骤实际上是过度杀伤,因为我们真正想要的只是每个键的第一个值。如果我们只选择具有不同键的对,我们可以避免分组和后续First
调用,如下所示:
var result = items.SelectMany(f => f.Dic)
.DistinctBy(pair => pair.Key)
.ToDictionary(pair => pair.Key, pair => pair.Value);
答案 1 :(得分:2)
var result =
(from item in items
from pair in item.Dic
group pair by pair.Key
).ToDictionary(g => g.Key, g => g.First().Value);
答案 2 :(得分:1)
我不知道Distinct
是否更好,但写作时间更短。
var result = items.SelectMany(d => d.Dic)
.Distinct()
.ToDictionary(p => p.Key, p => p.Value);
但实际上我有点喜欢使用foreach
。
var result = new Dictionary<int, bool>();
foreach (var dic in items.SelectMany(d => d.Dic))
result[dic.Key] = dic.Value;