c#字典一键多值

c#字典一键多值,c#,.net,dictionary,datasource,C#,.net,Dictionary,Datasource,我想创建一个数据存储来存储一些数据 第一个想法是创建一个字典,其中有一个键和多个值,所以有点像一对多关系 我认为这本字典只有一个键值 我还可以如何存储此信息?您可以使用第二个泛型类型的列表。例如,由字符串键入的字符串字典: Dictionary<string, List<string>> myDict; 字典myDict; 您可以使用字典 这将允许每个键引用一个值列表。您可以拥有一个字典,其中包含一个集合(或任何其他类型/类)作为值。这样,您就有了一个键,并将值存储在集

我想创建一个数据存储来存储一些数据

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

我认为这本字典只有一个键值


我还可以如何存储此信息?

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

Dictionary<string, List<string>> myDict;
字典myDict;

您可以使用
字典


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

您可以拥有一个字典,其中包含一个集合(或任何其他类型/类)作为值。这样,您就有了一个键,并将值存储在集合中。

一个.NET字典对键和值只有一对一的关系。但这并不意味着一个值不能是另一个数组/列表/字典

我想不出有什么理由在字典里有一对多的关系,但显然有一个


如果要将不同类型的数据存储到一个键中,那么这听起来是创建自己的类的理想时机。然后是1对1,但值类存储的数据多于1条。

词典的值类型可以是列表,也可以是其他包含多个对象的类。差不多

Dictionary<int, List<string>> 
字典
对于由int键控并包含字符串列表的字典

选择值类型时的一个主要考虑因素是使用字典的目的,如果必须对值执行搜索或其他操作,那么可以考虑使用一种数据结构来帮助您完成所需操作,例如哈希集。

使用列表字典(或其他类型的集合),例如:

var myDictionary = new Dictionary<string, IList<int>>();

myDictionary["My key"] = new List<int> {1, 2, 3, 4, 5};
var myDictionary=newdictionary();
myDictionary[“My key”]=新列表{1,2,3,4,5};

从.net3.5+开始,您可以使用Linq命名空间中的
查找,而不是使用
字典

// 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];
//按付款状态查找订单(1:m)
//需要像字典订单一样的东西
ILookup byPayment=orderList.ToLookup(o=>o.IsPayed);
IEnumerable Paydorders=byPayment[假];
发件人:

查找类似于词典。这个 不同之处在于,字典将键映射到单个 值,而查找将键映射到 价值观

您可以通过调用 在实现IEnumerable的对象上执行ToLookup

你可能还想读一本书。有关更多信息,请咨询

完整示例:

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;
            }
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
名称空间linqlookupsike
{
班级计划
{
静态void Main(字符串[]参数)
{
//初始化
var orderList=新列表();
orderList.Add(新订单(1,12010,true));/(orderId,customerId,year,isPayed)
添加(新订单(2,22010,true));
添加(新订单(3,1,2010,true));
orderList.Add(新订单(4,2,2011,true));
orderList.Add(新订单(5,2,2011,false));
orderList.Add(新订单(6,1,2011,true));
orderList.Add(新订单(7,3,2012,false));
//按id的查找顺序(1:1,所以普通字典可以)
字典顺序=orderList.ToDictionary(o=>o.OrderId,o=>o);
//按客户列出的查找顺序(1:n)
//需要像Dictionary orderIdByCustomer这样的东西
ILookup byCustomerId=orderList.ToLookup(o=>o.CustomerId);
foreach(byCustomerId中的var customerOrders)
{
WriteLine(“Customer{0}ordered:”,customerOrders.Key);
foreach(客户订单中的var订单)
{
WriteLine(“订单{0}已付款:{1}”、Order.OrderId、Order.IsPayed);
}
}
//使用老式字典也是一样
字典顺序IDbyCustomer;
orderIdByCustomer=byCustomerId.ToDictionary(g=>g.Key,g=>g.ToList());
foreach(orderIdByCustomer中的var customerOrders)
{
WriteLine(“Customer{0}ordered:”,customerOrders.Key);
foreach(customerOrders.Value中的变量顺序)
{
WriteLine(“订单{0}已付款:{1}”、Order.OrderId、Order.IsPayed);
}
}
//按付款状态查找订单(1:m)
//需要像字典订单一样的东西
ILookup byPayment=orderList.ToLookup(o=>o.IsPayed);
IEnumerable Paydorders=byPayment[假];
foreach(付款人中的var付款人)
{
WriteLine(“来自客户{1}的订单{0}未付款。”,payedOrder.OrderId,payedOrder.CustomerId);
}
}
阶级秩序
{
//关键属性
公共Int32 OrderId{get;private set;}
public Int32 CustomerId{get;private set;}
公共Int32年{get;私有集;}
公共布尔值IsPayed{get;private set;}
//附加属性
//私人物品清单;
公共秩序(Int32 orderId、Int32 customerId、Int32 year、Boolean iPayed)
{
OrderId=OrderId;
CustomerId=CustomerId;
年=年;
IsPayed=IsPayed;
}
}
}
}
关于不变性的评论

默认情况下,查找是不可变的,访问
内部
将涉及反射。 如果您需要可变性并且不想编写自己的包装器,那么可以使用(以前称为) 从(以前的一部分不再更新)。

使用以下方法:

Dictionary<TKey, Tuple<TValue1, TValue2, TValue3, ...>>
字典
public abstract class Lookup<TKey, TElement> : KeyedCollection<TKey, ICollection<TElement>>
{
  protected override TKey GetKeyForItem(ICollection<TElement> item) =>
    item
    .Select(b => GetKeyForItem(b))
    .Distinct()
    .SingleOrDefault();

  protected abstract TKey GetKeyForItem(TElement item);

  public void Add(TElement item)
  {
    var key = GetKeyForItem(item);
    if (Dictionary != null && Dictionary.TryGetValue(key, out var collection))
      collection.Add(item);
    else
      Add(new List<TElement> { item });
  }

  public void Remove(TElement item)
  {
    var key = GetKeyForItem(item);
    if (Dictionary != null && Dictionary.TryGetValue(key, out var collection))
    {
      collection.Remove(item);
      if (collection.Count == 0)
        Remove(key);
    }
  }
}
public class Item
{
  public string Key { get; }
  public string Value { get; set; }
  public Item(string key, string value = null) { Key = key; Value = value; }
}

public class Lookup : Lookup<string, Item>
{
  protected override string GetKeyForItem(Item item) => item.Key;
}

static void Main(string[] args)
{
  var toRem = new Item("1", "different");
  var single = new Item("2", "single");
  var lookup = new Lookup()
  {
    new Item("1", "hello"),
    new Item("1", "hello2"),
    new Item(""),
    new Item("", "helloo"),
    toRem,
    single
  };

  lookup.Remove(toRem);
  lookup.Remove(single);
}
 List<KeyValuePair<string, string>> Mappings;
public class MultiDictionary<TKey, TValue> : Dictionary<TKey, List<TValue>>
{
    public void Add(TKey key, TValue value)
    {
        if (TryGetValue(key, out List<TValue> valueList)) {
            valueList.Add(value);
        } else {
            Add(key, new List<TValue> { value });
        }
    }
}
MultiValueDictionary<string, string> Parameters = new MultiValueDictionary<string, string>();

Parameters.Add("Malik", "Ali");
Parameters.Add("Malik", "Hamza");
Parameters.Add("Malik", "Danish");

//Parameters["Malik"] now contains the values Ali, Hamza, and Danish
 Dictionary<int, string[]> dictionaty  = new Dictionary<int, string[]>() {
            {1, new string[]{"a","b","c"} },
            {2, new string[]{"222","str"} }
        };