【问题标题】:Return list with more than one value stored in a dictionary using linq使用 linq 将多个值存储在字典中的返回列表
【发布时间】:2013-11-29 12:07:13
【问题描述】:

我有一个定义如下的字典:Dictionary<string, List<int>>,我想进行过滤,以便它只包含 List<Int> 中包含超过 1 个值的条目。

下面的代码正确构建了我的字典(感谢 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 =&gt; m.Value.Count &gt; 1),认为这样可以解决问题,但它给出了“隐式转换”错误。

【问题讨论】:

    标签: c# linq


    【解决方案1】:

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

    .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&lt;KeyValuePair&lt;string, List&lt;int&gt;&gt;&gt;。但是,您正在尝试将此值分配给类型为具体字典的变量,这是键值对的可枚举列表的特例,编译器必须阻止您这样做以保证类型安全。

    如果您将fieldNameList 的类型更改为上述类型,则该行将编译,但您稍后将无法使用IDictionary&lt;K, V&gt; 接口。

    【讨论】:

    • 一个简单的问题,使用.Any() 不会比.Count() 更有效吗?
    • 妈的,太快了!! :)... 谢谢。这正是我所需要的。令人沮丧的是,我发誓我也尝试过,但显然我做错了!再次感谢!
    • @DavidPilkington:它必须大于 1,这样才行不通。
    • @DavidPilkington 如果使用Any(),应该是.Skip(1).Any(),看起来更好但不知何故不是真的,我测试了2个代码,看起来.Count()版本更快?很奇怪。
    • @DavidPilkington:请看一下 cmets here,我的意思是开始枚举分组结果要求首先完全实现该组(否则机会对于可怕的性能),因此在恒定时间内获得计数所需的信息已经存在。因此,如果 BCL 不像数组和列表那样利用它,那将是“愚蠢的”,而且确实如此。
    【解决方案2】:

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

    正如 Jon 解释的那样,字典上的 Where 返回一个 IEnumerable&lt;KeyValuePair&lt;string, List&lt;int&gt;&gt;&gt;,您只需要将键和值对分离成字典的键和值:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多