c#dictionary一键多个值

Mar*_*c G 63 .net c# dictionary datasource

我想创建一个数据存储,以允许我存储一些数据.

第一个想法是创建一个字典,其中有1个具有许多值的键,所以有点像一对多的关系.

我认为字典只有1个键值.

我怎么能存储这些信息?

mbx*_*mbx 69

从.net3.5 +开始,而不是使用a,Dictionary<IKey, List<IValue>>你可以使用LookupLinq命名空间中的一个:

// lookup Order by payment status (1:m) 
// would need something like Dictionary<Boolean, IEnumerable<Order>> orderIdByIsPayed
ILookup<Boolean, Order> byPayment = orderList.ToLookup(o => o.IsPayed);
IEnumerable<Order> payedOrders = byPayment[false];
Run Code Online (Sandbox Code Playgroud)

来自msdn:

查找类似于字典.区别在于Dictionary将键映射到单个值,而Lookup将键映射到值集合.

您可以通过在实现IEnumerable的对象上调用ToLookup来创建Lookup实例.

您可能还需要阅读这个答案相关问题.有关更多信息,请咨询msdn.

完整示例:

using System;
using System.Collections.Generic;
using System.Linq;

namespace LinqLookupSpike
{
    class Program
    {
        static void Main(String[] args)
        {
            // init 
            var orderList = new List<Order>();
            orderList.Add(new Order(1, 1, 2010, true));//(orderId, customerId, year, isPayed)
            orderList.Add(new Order(2, 2, 2010, true));
            orderList.Add(new Order(3, 1, 2010, true));
            orderList.Add(new Order(4, 2, 2011, true));
            orderList.Add(new Order(5, 2, 2011, false));
            orderList.Add(new Order(6, 1, 2011, true));
            orderList.Add(new Order(7, 3, 2012, false));

            // lookup Order by its id (1:1, so usual dictionary is ok)
            Dictionary<Int32, Order> orders = orderList.ToDictionary(o => o.OrderId, o => o);

            // lookup Order by customer (1:n) 
            // would need something like Dictionary<Int32, IEnumerable<Order>> orderIdByCustomer
            ILookup<Int32, Order> byCustomerId = orderList.ToLookup(o => o.CustomerId);
            foreach (var customerOrders in byCustomerId)
            {
                Console.WriteLine("Customer {0} ordered:", customerOrders.Key);
                foreach (var order in customerOrders)
                {
                    Console.WriteLine("    Order {0} is payed: {1}", order.OrderId, order.IsPayed);
                }
            }

            // the same using old fashioned Dictionary
            Dictionary<Int32, List<Order>> orderIdByCustomer;
            orderIdByCustomer = byCustomerId.ToDictionary(g => g.Key, g => g.ToList());
            foreach (var customerOrders in orderIdByCustomer)
            {
                Console.WriteLine("Customer {0} ordered:", customerOrders.Key);
                foreach (var order in customerOrders.Value)
                {
                    Console.WriteLine("    Order {0} is payed: {1}", order.OrderId, order.IsPayed);
                }
            }

            // lookup Order by payment status (1:m) 
            // would need something like Dictionary<Boolean, IEnumerable<Order>> orderIdByIsPayed
            ILookup<Boolean, Order> byPayment = orderList.ToLookup(o => o.IsPayed);
            IEnumerable<Order> payedOrders = byPayment[false];
            foreach (var payedOrder in payedOrders)
            {
                Console.WriteLine("Order {0} from Customer {1} is not payed.", payedOrder.OrderId, payedOrder.CustomerId);
            }
        }

        class Order
        {
            // key properties
            public Int32 OrderId { get; private set; }
            public Int32 CustomerId { get; private set; }
            public Int32 Year { get; private set; }
            public Boolean IsPayed { get; private set; }

            // additional properties
            // private List<OrderItem> _items;

            public Order(Int32 orderId, Int32 customerId, Int32 year, Boolean isPayed)
            {
                OrderId = orderId;
                CustomerId = customerId;
                Year = year;
                IsPayed = isPayed;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

关于不变性的评论

默认情况下,Lookups是不可变的,访问internals会涉及反射.如果你需要可变性并且不想编写自己的包装器,你可以使用MultiValueDictionary(以前称为MultiDictionary)corefxlab(以前的部分Microsoft.Experimental.Collections不再更新).


Ode*_*ded 53

您可以使用第二种泛型类型的列表.例如,由字符串键入的字符串字典:

Dictionary<string, List<string>> myDict;
Run Code Online (Sandbox Code Playgroud)


小智 16

微软刚刚在NuGet上添加了一个官方预发布版本,你正在寻找什么(称为MultiDictionary):https://www.nuget.org/packages/Microsoft.Experimental.Collections/

有关使用情况和更多详细信息,请访问官方MSDN博客文章:http://blogs.msdn.com/b/dotnet/archive/2014/06/20/would-you-like-a-multidictionary.aspx

我是此软件包的开发人员,如果您对性能或任何问题有任何疑问,请在此处或MSDN上告诉我.

希望有所帮助.

更新

MultiValueDictionary现在的corefxlab回购,你可以从NuGet包这个 MyGet饲料.


Gis*_*way 8

用这个:

Dictionary<TKey, Tuple<TValue1, TValue2, TValue3, ...>>
Run Code Online (Sandbox Code Playgroud)


Tim*_*ely 7

字典的值类型可以是List,也可以是包含多个对象的其他类.就像是

Dictionary<int, List<string>> 
Run Code Online (Sandbox Code Playgroud)

对于由ints键入的字典并保存字符串列表.

选择值类型的一个主要考虑因素是你将使用词典,如果你必须对值进行搜索或其他操作,那么可以考虑使用一种数据结构来帮助你做你想做的事情 - - 像HashSet一样.


Blo*_*ard 5

你可以用一个Dictionary<TKey, List<TValue>>.

这将允许每个键引用值列表.