为了账号安全,请及时绑定邮箱和手机立即绑定

C#字典一键很多值

/ 猿问

C#字典一键很多值

慕村225694 2019-11-15 10:42:39

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

第一个想法是创建一个字典,在该字典中您拥有一个带有多个值的键,因此有点像一对多的关系。

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

我还能如何存储此信息?


查看完整描述

3 回答

?
撒科打诨

从.net3.5 +开始,Dictionary<IKey, List<IValue>>可以使用LookupLinq命名空间中的a 来代替使用a :


// 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];

来自msdn:


查找类似于字典。区别在于字典将键映射到单个值,而查阅将键映射到值的集合。


您可以通过在实现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;

            }

        }

    }

}

关于不变性的评论


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


查看完整回答
反对 回复 2019-11-15
?
慕神8447489

微软刚刚通过NuGet在此处添加了您正在寻找的确切的正式prelease版本(称为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饲料。


查看完整回答
反对 回复 2019-11-15
?
45度呼吸

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


Dictionary<int, List<string>> 

用于由int键控并包含字符串列表的Dictionary。


选择值类型的主要考虑因素是将使用Dictionary的目的,如果您必须对值进行搜索或其他操作,那么也许考虑考虑使用一种可以帮助您完成所需工作的数据结构- -像HashSet。


查看完整回答
反对 回复 2019-11-15

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信