将名称列表转换为字典,其中每个条目对应于以某个字母开头的名称
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<Employee>
作为输入并需要Dictionary<string,List<Employee>>
作为输出,所以请不要说我需要返回其他内容。
【问题讨论】:
【参考方案1】:听起来你真的想要一个ILookup<string, Employee>
,它恰好是一个字典,其中每个键都映射到可能的多个值。是的,您可以创建Dictionary<string, List<Employee>>
,但我强烈建议您不要这样做。你说你“需要”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
,因为您只处理单个字符 - 并且还要考虑您希望对姓氏发生什么,例如“de Havilland” " 或以重音字符开头的字符。 (换句话说,您可能想要执行一些规范化。)
【讨论】:
哇,你打字这么快,在LastName
上使用Substring
比First
有优势吗(这是我对你的回答的唯一区别)
@sa_ddam213:好吧,First
将返回 char
而不是 string
.... 那时您不妨使用 [0]
。
啊,没关系,char
与 string
会是我猜的答案 :)
您好乔恩,感谢您的回答。但是有一个问题。我真的需要一份员工名单。我将它用于 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);
它是一个简单的控制台应用程序
【讨论】:
以上是关于将名称列表转换为字典,其中每个条目对应于以某个字母开头的名称的主要内容,如果未能解决你的问题,请参考以下文章