使用LINQ从另一个字典创建字典

24

我有一个字典,格式如下:

IDictionary<foo, IEnumerable<bar>> my_dictionary

bar类看起来像这样:

class bar
{
    public bool IsValid {get; set;} 
}

我该如何创建另一个字典,其中仅包含 IsValid = true 的那些项。

我尝试过以下代码:

my_dictionary.ToDictionary( p=> p.Key,
                            p=> p.Value.Where (x => x.IsValid));
以上代码的问题在于,如果该键对应的所有元素 IsValid 均为 false,则会创建一个具有空可枚举项的键。
例如:
my_dictionar[foo1] = new List<bar> { new bar {IsValid = false}, new bar {IsValid = false}, new bar {IsValid = false}};
my_dictionary[foo2] = new List<bar> {new bar {IsValid = true} , new bar{IsValid = false};
var new_dict = my_dictionary.ToDictionary( p=> p.Key,
                            p=> p.Value.Where (x => x.IsValid));
// Expected new_dict should contain only foo2 with a list of 1 bar item.
// actual is a new_dict with foo1 with 0 items, and foo2 with 1 item.

如何获得我所期望的结果。

3个回答

41

像这样吗?

my_dictionary
    .Where(p=> p.Value.Any(x => x.IsValid))
    .ToDictionary( p=> p.Key,
                   p=> p.Value.Where (x => x.IsValid));

这将只包括那些至少有一个值为 IsValid 的项目。


1
+1 OP需要在调用ToDictionary之前使用Where来过滤集合。 - Kirk Broadhurst
这个第一个 Where 子句不足以摆脱 x=>!x.IsValid 吗?您不能只写 .ToDictionary(p=>p.Key, p=>p.Value),因为在调用 ToDictionary 之前的 where 子句已经应用了过滤吗? - Prokurors
1
@Prokurors:不,因为我们正在处理一个 IEnumerable<KeyValuePair<foo, IEnumerable<bar>>>,所以情况比那更复杂一些。第一个 .Where() 是检查每个 KeyValuePair 中是否有任何一个 bar 是有效的,但它实际上并没有过滤 bar 本身只包括有效的。如果你有一个 KeyValuePair,其值包含有效和无效的混合,那么无效的仍然需要稍后被过滤掉。 - StriplingWarrior

1
my_dictionary.Where(p => p.Any(v => v.Value.IsValid())
             .ToDictionary(p=> p.Key,
                           p=> p.Value.Where(x => x.Value.IsValid());

获取值为 true 的项,然后将这些 true 项放入新字典中。

过滤后创建字典。


1
var new_dict = my_dictionary.Select(x => new KeyValuePair<foo, List<bar>>(
                                                 x.Key,
                                                 x.Value
                                                  .Where(y => y.IsValid)
                                                  .ToList()))
                            .Where(x => x.Value.Count > 0)
                            .ToDictionary(x => x.Key, x => x.Value.AsReadOnly());

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接