2014-09-24 31 views
0

我創建了一些方法,該方法在此方法中返回Dictionary<string, List<Employee>> i通過List<Employee>循環並查找名字並將其按字母順序添加到我的字典中將名稱列表轉換爲字典,其中每個條目對應於以某個字母開頭的名稱

請看下面的例子:

  • 員工
    • Eijk,約迪
    • 李四,約翰
    • Doe的,簡

其中第一部分是姓氏和第二部分是姓

我的方法創建一個字典這樣

  • 「D」,列表({Doe,John},{Doe,Jane})
  • 「E」,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>>作爲輸出,所以請不要說我需要返回其他內容。

回答

8

這聽起來像你真的想要一個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」或者以重音字符開頭的名字。 (換句話說,你可能需要執行規範化。)

+0

哇,你鍵入得這麼快,是有一個優勢,使用'Substring'了'First'上'LastName'(也就是我的回答你,唯一的區別) – 2014-09-24 22:23:47

+2

@ sa_ddam213:那麼'First'將返回一個'char'而不是'string' ....你可能在那時使用'[0]''。 – 2014-09-24 22:24:56

+0

ahh,沒關係,'char' vs'string'會是我猜的答案:) – 2014-09-24 22:25:20

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); 
    } 
} 
} 

它是一種簡單的控制檯應用程序

相關問題