【问题标题】:Keep Where() consistent for Dictionary [duplicate]保持字典的 Where() 一致[重复]
【发布时间】:2012-06-26 14:06:06
【问题描述】:

可能重复:
Recreating a Dictionary from an IEnumerable

当在 Dictionary<TKey, TValue> 类型的字典上使用 Where 方法时,您最终会得到 IEnumerable<KeyValuePair<TKey, TSource>>,这破坏了我在开始时选择的数据类型。我想返回一本字典。

也许我没有使用正确的过滤功能。那么你通常如何从字典中过滤元素呢?

谢谢

【问题讨论】:

标签: c# dictionary


【解决方案1】:

IDictionary<TKey, TValue> 实际上扩展了IEnumerable<KeyValuePair<TKey, TValue>>。这就是为什么您首先可以在 IDictionary<TKey, TValue> 上使用 LINQ 运算符的原因。

但是,LINQ 运算符返回 IEnumerable<T>,它旨在提供 deferred execution,这意味着在您开始迭代 IEnumerable<T> 之前不会真正生成结果。

IDictionary<TKey, TValue> 提供的IEnumerable<T> 实现来自ICollection<T> interface(其中TKeyValuePair<TKey, TValue>),这意味着如果LINQ 返回IDictionary<TKey, TValue> 而不是@987654337 @ 然后它必须实现列表,违反它的原则(因此 IEnumerable<KeyValuePair<TKey, TValue>> 返回值)。

当然,绕过它的方法是在 Enumerable class 上调用 ToDictionary 扩展方法(正如其他人提到的那样),但一点点背景故事永远不会受到伤害。

【讨论】:

  • 恕我直言,让字典“继承”所有 LINQ 查询并不是一个好主意,尤其是延迟执行对于字典来说并不是一个有趣的功能。一个更简洁的 API 和接受闭包的正确方法会更好。
  • @mathk 这不是字典的真正问题,而是它实现了ICollection<T> 的事实;你的建议是任何实现ICollection<T> 的东西都会在 each 操作之后实现它的结果集。这是高度低效的,因为您必须在 each 查询操作(every selectwhere、@ 987654346@等)。
  • 这不是我要说的。我是说它不应该继承所有 LINQ qyuery。对字典进行查询操作并没有多大意义。尤其是查询表达式是惰性求值的,它不如 Haskell 惰性求值。
  • @mathk 我明白你在说什么,但是你要么必须a)从IDictionary<TKey, TValue> 中删除ICollection<T> 实现(这没有多大意义)或b)找到一种方法来告诉类型推断不用于类型的特定派生。 IMO,这两个提议都不太吸引人。
  • 是的,我认为 Dictionary API 没有很好地实现我宁愿让 Dictionary 实现一个接口,例如:interface IDctionary<TKey, TValue> { Dictionary<TKey, TResult> Collect<TResult>(Func<TKey, TValue, TResult> collector); Dictionary<TKey, TValue> Reject(Func<TKey, TValue, Boolean> predicate); Dictionary<TKey, TValue> Select(Func<TKey, TValue, Boolean> predicate); // The correct meaning of select void Do(Func<TKey, TValue> block); ... }
【解决方案2】:

.ToDictionary()到底怎么样?

【讨论】:

    【解决方案3】:

    在您的 LINQ 表达式中使用 .ToDictionary();

    【讨论】:

    • @downvoter 愿意发表评论吗?
    【解决方案4】:

    您可以使用Where(),然后使用ToDictionary()

    var newDict = yourDict.Where(pair => SomePredicateFrom(pair))
                          .ToDictionary(pair => pair.Key, pair => pair.Value);
    

    【讨论】:

    • 我通常避免使用 To*() 方法。尤其是这个服用 2 lambda 的人。听起来我在用剑切面包。但如果 API 强迫我这样做,我别无选择。
    猜你喜欢
    • 2018-04-15
    • 1970-01-01
    • 2020-11-05
    • 1970-01-01
    • 2016-03-06
    • 2012-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多