在字典中键值的列表中插入值

本文关键字:插入 列表 键值 字典 | 更新日期: 2023-09-27 18:15:06

我有一个rowsDictionary,它的键指向EmployeeSummary类的列表。在EmployeeSummary类中我们也有Delivery_System

的字符串属性

我以这种方式循环,但现在卡住了,我想有一个deliverySystemFinder dictioanry,它的键是combinedKey,如下所示,每个键的值是一个不同的delivery_system值的列表

//rowsDictionary is a Dictionary<string, List<EmployeeSummary>>
Dictionary<string, List<string>> deliverySystemFinder = new Dictionary<string, List<string>>();
foreach (string key in rowsDictionary.Keys)
{
    List<EmployeeSummary> empList = rowsDictionary[key];
    foreach (EmployeeSummary emp in empList)
    {
        string combinedKey = emp.LastName.Trim().ToUpper() + emp.FirstName.Trim().ToUpper();
        string delivery_system = emp.Delivery_System;
        // so now I should go and 
        //A) does deliverySystemFinder have this combinedKey? if not add it. 
        //B) Does combinedKey in the list of its values already have the value for delivery_system? if it does not then add it 
    }
}

在字典中键值的列表中插入值

这可以,对于start:

foreach (string key in rowsDictionary.Keys)
{
    List<EmployeeSummary> empList = rowsDictionary[key];
    foreach (EmployeeSummary emp in empList)
    {
        string combinedKey = emp.LastName.Trim().ToUpper() +
            emp.FirstName.Trim().ToUpper();
        string delivery_system = emp.Delivery_System;
        List<string> systems = null;
        // check if the dictionary contains the list
        if (!deliverySystemFinder.TryGetValue(combinedKey, out systems))
        {
            // if not, create it and add it 
            systems = new List<string>();
            deliverySystemFinder[combinedKey] = systems;
        }
        // check if the list contains the value and add it
        if (!systems.Contains(delivery_system))
            systems.Add(delivery_system);
    }
}

现在,一些注释:

  1. 通过Keys进行迭代,然后在每次迭代中进行查找是没有意义的。您可以使用foreach循环直接迭代KeyValuePair s。

  2. 使用连接字符串作为唯一键通常会失败。在这种情况下,如果列表中有用户{ LastName="Some", FirstName="Body" }{ LastName="So", FirstName="Mebody" },会发生什么?

  3. 检查List是否包含值为O(n)操作。如果您使用HashSet<string>来代替,您将大大提高性能。

最后,实现您想要做的事情的最简单的方法是放弃这些循环并简单地使用:

// returns a Dictionary<EmployeeSummary, List<string>>
// which maps each distinct EmployeeSummary into a list of
// distinct delivery systems
var groupByEmployee = rowsDictionary
    .SelectMany(kvp => kvp.Value)
    .GroupBy(s => s, new EmployeeSummaryEqualityComparer())
    .ToDictionary(
         s => s.Key, 
         s => s.Select(x => x.Delivery_System).Distinct().ToList());

使用EmployeeSummaryEqualityComparer定义如下:

class EmployeeSummaryEqualityComparer : IEqualityComparer<EmployeeSummary>
{
    public bool Equals(EmployeeSummary x, EmployeeSummary y)
    {
        if (object.ReferenceEquals(x, null))
            return object.ReferenceEquals(y, null);
        return 
            x.FirstName == y.FirstName &&
            x.LastName == y.LastName &&
            ... (depending on what constitutes 'equal' for you)
    }
    public int GetHashCode(EmployeeSummary x)
    {
        unchecked
        {
            var h = 31;   // null checks might not be necessary?
            h = h * 7 + (x.FirstName != null ? x.FirstName.GetHashCode() : 0);
            h = h * 7 + (x.LastName != null ? x.LastName.GetHashCode() : 0);
            ... other properties similarly ...
            return h;
        }
    }
}

如果你真的认为使用string键可以在所有情况下工作,你可以不使用自定义相等比较器:

// returns a Dictionary<string, List<string>>
var groupByEmployee = rowsDictionary
    .SelectMany(kvp => kvp.Value)
    .GroupBy(s => s.LastName.ToUpper() + s.FirstName.ToUpper())
    .ToDictionary(
         s => s.Key,
         s => s.Select(x => x.Delivery_System).Distinct().ToList());