【问题标题】:Creating a dictionary from another dictionary using LINQ使用 LINQ 从另一个字典创建字典
【发布时间】:2011-08-16 06:04:12
【问题描述】:

我有一本这样的字典:

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.

我如何得到我的期望。

【问题讨论】:

    标签: c# linq


    【解决方案1】:

    这样的?

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

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

    【讨论】:

    • +1 OP 需要在调用ToDictionary 之前使用Where 过滤集合
    • 第一个 Where 子句是否不足以摆脱 x=>!x.IsValid ?你能不能只写 .ToDictionary(p=>p.Key, p=>p.Value),因为调用 ToDictionary 之前的 where 子句已经在应用过滤?
    • @Prokurors:不,因为我们正在处理IEnumerable&lt;KeyValuePair&lt;foo, IEnumerable&lt;bar&gt;&gt;&gt;,它比这更复杂一些。第一个 .Where() 检查每个 KeyValuePair 中的 any bar 是否有效,但实际上并没有过滤 bars 本身以仅包含有效的。如果您有一个 KeyValuePair,其值包含有效和无效的混合,那么稍后仍需要过滤掉无效的值。
    【解决方案2】:
    my_dictionary.Where(p => p.Any(v => v.Value.IsValid())
                 .ToDictionary(p=> p.Key,
                               p=> p.Value.Where(x => x.Value.IsValid());
    

    仅获取 Value 中为 true 的项,然后仅将为 true 的项获取到新字典中。

    过滤然后创建字典

    【讨论】:

      【解决方案3】:
      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());
      

      【讨论】:

        猜你喜欢
        • 2021-03-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-10-05
        • 1970-01-01
        • 2021-05-15
        相关资源
        最近更新 更多