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

时间:2014-09-24 22:14:09

标签: c# list dictionary

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

请看以下示例:

  • 员工
    • Eijk,Jordy
    • Doe,John
    • Doe,Jane
    • 等。

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

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

  • &#34; D&#34;,List({Doe,John},{Doe,Jane})
  • &#34; E&#34;,List({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<Employee>作为输入,并需要Dictionary<string,List<Employee>>作为输出,所以请不要说我需要返回其他内容。

2 个答案:

答案 0 :(得分:8)

听起来你真的想要一个ILookup<string, Employee>,它恰好是一个字典,每个键都映射到可能有多个值。是的,您可以创建Dictionary<string, List<Employee>>,但我强烈建议您不要。你说你需要&#34;需要&#34; Dictionary<string,List<Employee>> - 为什么?

查找代码为:

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而不是{{1}},因为您只处理单个字符 - 并且还要考虑您希望持续发生的事情诸如&#34; de Havilland&#34;等名称或以重音字符开头的。 (换句话说,您可能希望执行一些规范化。)

答案 1 :(得分:0)

我很抱歉不相信你;)

它确实像预期的那样工作。在查找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);
    }
}
}

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