使用linq将包含多个值的返回列表存储在字典中

时间:2013-11-29 12:07:14

标签: c# linq

我有一个字典定义如下:Dictionary<string, List<int>>我希望进行过滤,以便只显示List<Int>中包含多个值的条目。

下面的代码正确构建了我的字典(感谢Andrew Whitaker)

Dictionary<string, List<int>> fieldNameList = 
    Mapping.Select(m => m.FieldName)
           .Select((c, i) => new { Value = c, Index = i })
           .GroupBy(o => o.Value, o => o.Index)
           .ToDictionary(grp => grp.Key, grp => grp.ToList());

但现在我需要对其进行过滤,以便只有包含多个项目的列表才会包含在最终字典中。

你是否介意解释额外的过滤器,因为我想了解我做错了什么。

我添加了现有查询的.Where(m => m.Value.Count > 1),认为这样可以解决问题,但它会产生“隐式转换”错误。

2 个答案:

答案 0 :(得分:5)

最早可以应用过滤器是在分组之后和创建字典之前:

.GroupBy(o => o.Value, o => o.Index)
.Where(g => g.Count() > 1)
.ToDictionary(grp => grp.Key, grp => grp.ToList());

这不需要任何解释;这是最有效的,因为它避免了首先在字典中添加你不想要的项目。

如果您想保留单项列表但仅在某些时候过滤掉它们,则需要使用

过滤字典
dict.Where(p => p.Value.Count > 1)

您最初的尝试

.ToDictionary(grp => grp.Key, grp => grp.ToList())
.Where(m => m.Value.Count > 1);

没有用,因为即使这是完全合理的事情,Where产生的结果类型也会是IEnumerable<KeyValuePair<string, List<int>>>。但是,您尝试将此值分配给作为具体字典键入的变量,这是一个可枚举的键值对列表的特例,编译器必须阻止您这样做才能保证类型安全。< / p>

如果您将fieldNameList的类型更改为上述内容,则此行将进行编译,但您稍后将无法使用IDictionary<K, V>界面。

答案 1 :(得分:0)

最简单的方法是在构建字典时过滤字典,但如果您需要非过滤字典和过滤字典,或者如果需要过滤现有字典,则可以再次调用.ToDictionary

正如Jon在字典上解释Where返回IEnumerable<KeyValuePair<string, List<int>>>,你只需要将密钥和值的值分成字典的键和值:

Dictionary<string, List<int>> resultDict = 
                       sourceDict.Where(kvp => kvp.Value.Count > 1)
                                 .ToDictionary(kvp => kvp.Key, kvp => kvp.Value);