将名称列表转换为字典,其中每个条目对应于以某个字母开头的名称

Posted

技术标签:

【中文标题】将名称列表转换为字典,其中每个条目对应于以某个字母开头的名称【英文标题】:Convert List of names to Dictionary, where each entry corresponds to names that begin with a certain letter 【发布时间】:2014-11-19 13:38:31 【问题描述】:

我创建了一些返回 Dictionary<string, List<Employee>> 的方法,在此方法中我循环遍历 List<Employee> 并查找名字并将其按字母顺序添加到我的字典中

看下面的例子:

员工 艾克,乔迪 Doe,约翰 Doe,简 等。

其中第一部分是姓氏,第二部分是名字

我的方法创建一个这样的字典

“D”,列表(Doe, John, Doe, Jane) “E”,列表 (Eijk, Jordy)

方法:

public async Task<Dictionary<string, List<Employee>>> GetAllOrderdedByNameAsync()
    
        var dbList = await _employeeRepository.ListAsync();
        var employees = dbList.Select(FromDb).ToList();
        var empDict = new Dictionary<string, List<Employee>>();
        for (char c = 'A'; c <= 'Z'; c++)
        
            var list = employees.Where(employee => employee.LastName.StartsWith(c.ToString(), StringComparison.CurrentCultureIgnoreCase)).ToList();
            if (list.Count > 0)
            
                empDict.Add(c.ToString(), list);
            
        
        return empDict;
    

现在我的问题...有没有更好的方法来做到这一点?我将保留List&lt;Employee&gt; 作为输入并需要Dictionary&lt;string,List&lt;Employee&gt;&gt; 作为输出,所以请不要说我需要返回其他内容。

【问题讨论】:

【参考方案1】:

听起来你真的想要一个ILookup&lt;string, Employee&gt;,它恰好是一个字典,其中每个键都映射到可能的多个值。是的,您可以创建Dictionary&lt;string, List&lt;Employee&gt;&gt;,但我强烈建议您不要这样做。你说你“需要”Dictionary&lt;string,List&lt;Employee&gt;&gt; - 为什么?

查找代码为:

var lookup = list.ToLookup(x => x.Substring(x.LastName(0, 1)),
                           StringComparer.CurrentCultureIgnoreCase);

要获取字典,如果你真的有充分的理由,你可以使用:

var dictionary = list.GroupBy(x => x.Substring(x.LastName(0, 1)))
                     .ToDictionary(g => g.Key, g => g.ToList(), 
                                   StringComparer.CurrentCultureIgnoreCase);

...但正如我所说,我会强烈建议使用已经准确表示您正在寻找的类型,以更简洁的方式。 (它还有一个很好的特性是允许你按任意键查找,如果没有条目则返回一个空序列。)

您可能还想考虑使用 char 作为您的密钥,而不是 string,因为您只处理单个字符 - 并且还要考虑您希望对姓氏发生什么,例如“de Havilland” " 或以重音字符开头的字符。 (换句话说,您可能想要执行一些规范化。)

【讨论】:

哇,你打字这么快,在LastName 上使用SubstringFirst 有优势吗(这是我对你的回答的唯一区别) @sa_ddam213:好吧,First 将返回 char 而不是 string.... 那时您不妨使用 [0] 啊,没关系,charstring 会是我猜的答案 :) 您好乔恩,感谢您的回答。但是有一个问题。我真的需要一份员工名单。我将它用于 GridView (StoreApp) 与分组的 CollectionViewSource @Jordy:如果你需要一个列表,你为什么要字典?如果您需要每个条目的列表,您可以随时在需要时从查找中调用每个项目的 ToList。【参考方案2】:

我很抱歉不相信你;)

它确实像它应该做的那样工作。在查找ILookup on MSDN 之后,仍然有点不清楚它是如何工作的。但我设法实现了它。

这里有一些示例代码,供所有想知道我是如何做到的人的。

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

namespace ConsoleSandbox

class Program

    static void Main(string[] args)
    
        var vm = new ViewModel();

        var lookupEmployees = vm.GetAllOrderedByName();

        foreach (var group in lookupEmployees)
        
            Console.WriteLine(group.Key);
            foreach (var employee in group)
            
                Console.WriteLine("\t"+employee);
            
        
        Console.Read();
    


public class ViewModel

    public ViewModel()
    
        //Fill Employees
        Employees = new List<Employee>
        
            new Employee FirstName = "Jordy", LastName = "Eijk van",
            new Employee FirstName = "Jon", LastName = "Skeet",
            new Employee FirstName = "John", LastName = "Doe",
            new Employee FirstName = "Jane", LastName = "Doe",
            new Employee FirstName = "Jack", LastName = "Ripper the"
        ;
    

    public List<Employee> Employees  get; set; 

    /// <summary>
    /// Get the Employees by name
    /// </summary>
    /// <returns></returns>
    public ILookup<string, Employee> GetAllOrderedByName()
    
        return Employees
            .OrderBy(e=>e.LastName)
            .ThenBy(e=>e.FirstName)
            .ToLookup(e => e.LastName.Substring(0, 1), StringComparer.CurrentCultureIgnoreCase);
    


public class Employee

    public string FirstName  get; set; 
    public string LastName  get; set; 

    public override string ToString()
    
        return string.Format("0 1", LastName, FirstName);
    


它是一个简单的控制台应用程序

【讨论】:

以上是关于将名称列表转换为字典,其中每个条目对应于以某个字母开头的名称的主要内容,如果未能解决你的问题,请参考以下文章

如何将分层列表排序为字典的树/pyrimid 模型?

每个键有多个值的列表到字典转换?

将字典中的数组转换为数组列表

将标准 python 键值字典列表转换为 pyspark 数据框

pandas:如何将字典转换为转置数据框? [复制]

将具有相同索引的熊猫系列列表转换为字典