【问题标题】:IEnumerable<T> to Dictionary<string, IEnumerable<T>> using LINQIEnumerable<T> 到 Dictionary<string, IEnumerable<T>> 使用 LINQ
【发布时间】:2012-09-17 07:06:24
【问题描述】:

拥有IEnumerable&lt;Order&gt; orders,如何使用Linq 获取Dictionary&lt;string, IEnumerable&lt;Order&gt;&gt;,其中键是Order.CustomerName 映射到客户订单的IEnumerable。

orders.ToDictionary(order =&gt; order.CustomerName) 不会立即起作用,因为可能有多个具有相同 CustomerName 的订单。

解决方案: orders.ToLookup(order =&gt; order.CustomerName);

【问题讨论】:

    标签: c# linq .net-3.5


    【解决方案1】:

    ILookup 接口就是为此目的而设计的,它表示一个类似字典的结构,每个键包含许多值。它具有与字典相似的性能特征(即它是哈希表类型结构)

    您可以使用.ToLookup 扩展方法创建ILookup,如下所示:

    ILookup<string, Order> ordersLookup = orders.ToLookup(o => o.CustomerName)
    

    然后:

    IEnumerable<Order> someCustomersOrders = ordersLookup[someCustomerName];
    

    【讨论】:

    • +1 这是一个很棒的界面。在今天之前从未听说过。
    • 大多数人不知道查找,但这是一个很好的使用示例。这比以枚举为值的字典更可取。
    • @SimpleCoder 它在 Linq2Objects 内部的所有地方都使用过
    • @spender:我得去看看。现在我正在做一个可能从 ILookup 中受益的项目,所以我必须尝试一下。
    【解决方案2】:

    只是@spender 答案的替代方案,如果你真的想要一个类型Dictionary&lt;string, IEnumerable&lt;Order&gt;&gt;,你可以使用:

    Dictionary<string, IEnumerable<Order>> dictionary = orders
            .GroupBy(order => order.CustomerName)
            .ToDictionary(groupedOrders => groupedOrders.Key, 
                              groupedOrders => (IEnumerable<Order>)groupedOrders);
    

    我确信有更好的方法,但也可以。

    【讨论】:

    • 为什么?如果你可以做 LINQ,你就可以做 ILookup,为什么要重新发明一个已经存在于你用来重新发明的库中的类。
    • @ScottChamberlain ILookup 和 Dictionary 之间的主要区别在于字典是可变的。如果您需要在创建后更改结果,则需要使用 Dictionary(在这种情况下,OP 可能需要不可变版本)。也可能存在类型为 Dictionary 的现有方法/属性,并且需要将其传递给它。
    • @ScottChamberlain - 一方面,OP 要求一本字典。 Dictionary 支持比查找更多的操作(例如可以修改),并且 OP 可能有一些需要字典的现有代码。
    • @ScottChamberlain 我更喜欢查找案例一般,甚至可能从查找到字典。 @CuongLe,感谢您的编辑;这好多了,我完全忘记了Key!
    • 好的,我现在明白了,但是@Lee 我正在做一些改造,我需要敲钉子,我应该使用Old Shoe or Glass Bottle吗?
    【解决方案3】:

    或者你可以简单地使用

    orders.ToLookup(o => o.CustomerName).ToDictionary(g => g.Key)
    

    但正如 Spender 的回答所示,也许您不需要最后一种方法 ToDictionary。

    【讨论】:

    • 仅供参考,这将创建一个Dictionary&lt;String, IGrouping&lt;String,Order&gt;&gt; 类型的字典。不确定这是否是 kateroh 的问题。 +1 虽然是为了简洁。
    • 没错。如果您不希望字典值上出现额外的“结构”,我想您可以说orders.ToLookup(o =&gt; o.CustomerName).ToDictionary&lt;string, Order&gt;(g =&gt; g.Key),如果我在脑海中以正确的方式转动IEnumerable&lt;&gt; 的协方差。
    猜你喜欢
    • 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
    相关资源
    最近更新 更多