1.ToDictionary,ToLookup
從圖中我們看到有四個ToXXX的方法,其中ToArray和ToList,用的是非常非常多
我們有這樣的一個實體
class student { public string StuNo { get; set; } //學號 public string Grand { get; set; } //年級 public string Sex { get; set; } //性別 }
年級和學號是一對多的關系,也就是說一個年級可能包含幾個學號,每個學號都有自己對應的性別
class Program { static void Main(string[] args) { } public static List<student> GetList() { return new List<student>() { new student(){StuNo="0001",Grand="一年級",Sex="男"}, new student(){StuNo="0002",Grand="二年級",Sex="男"}, new student(){StuNo="0003",Grand="一年級",Sex="女"}, new student(){StuNo="0004",Grand="一年級",Sex="男"}, new student(){StuNo="0005",Grand="二年級",Sex="男"}, new student(){StuNo="0006",Grand="一年級",Sex="女"}, new student(){StuNo="0007",Grand="二年級",Sex="男"}, new student(){StuNo="0008",Grand="一年級",Sex="男"}, new student(){StuNo="0009",Grand="二年級",Sex="女"}, new student(){StuNo="0010",Grand="一年級",Sex="男"}, new student(){StuNo="0011",Grand="三年級",Sex="女"}, new student(){StuNo="0012",Grand="一年級",Sex="人妖"}, new student(){StuNo="0013",Grand="三年級",Sex="女"} }; } }
這種初始化類對象的方法以及返回方式:
student s= new student() { Sex = "nan" };
舉個例子: 我需要統計各個年級中的學號情況。
很明顯,這是一個分組排序的問題,可能你馬上就想起了groupby來實現,當然groupby是可以實現的,不過groupby不能算是一種數據結構,不能帶有索引,沒有字典那樣容易輸出和操作。
方案一: 采用普通的foreach循環。
一般情況下,可能有一部分人都采用這種原始的方法,將list數據通過foreach循環放到dictionary中,就是代碼寫的多一些,也算是最靈活的。
static void Main(string[] args) { Dictionary<int, student> dic = new Dictionary<int, student>(); List<student> stulist = GetList(); foreach (var item in stulist) { if (!dic.ContainsKey(item.Grand)) { dic.Add(item.Grand, item); } else { dic[item.Grand] = item; } } }
結果
方案二:使用ToDictionary
Dictionary是一種鍵值方式(值是一個對象)
從圖中我們可以看到,發生悲劇的異常了,我們知道dictionary中key是不能重復的,然而ToDictionary中並沒有給我們做key的重復值判斷,那也就側面說明ToDictionary在kv中只能是 “一對一”的關系,也就是v中永遠只會有一條記錄,顯然這不是我需要的,在了解ToDictionary原理后,該方案失敗。
如果沒有重復的
class Program { static void Main(string[] args) { List<student> stulist = GetList(); var dic = stulist.ToDictionary(m=>m.Grand); } public static List<student> GetList() { return new List<student>() { new student(){StuNo="0001",Grand=1,Sex="男"}, new student(){StuNo="0002",Grand=2,Sex="男"}, new student(){StuNo="0003",Grand=3,Sex="女"}, }; } }
結果是
Dictionary的下標只能是鍵
方案三: 使用ToLookup(鍵值對,值是一組對象)
ToDictionary的加強版,可以認為是一種新的字典數據結構,它就避免了這種“一對一”的關系,采用“一對多”的實現。
static void Main(string[] args) { var stulist = GetList(); var dic = stulist.ToLookup(i=>i.Grand); foreach (var item in dic) { Console.WriteLine("年級:" + item.Key); foreach (var item1 in item) { Console.WriteLine("\t\t" + item1.StuNo + " " + item1.Sex); } } }
結果
而且ToLookup和字典一樣,是帶有索引形式,這個groupby就不具備了,當然Tolookup還有一個強大的功能,就是使用Func<TSource, TElement> elementSelector來對現在的v元素進行轉換來避免剛才 Console.WriteLine("\t\t" + item1.TicketNo + " " + item1.Description);語句
static void Main(string[] args) { var stulist = GetList(); var dic = stulist.ToLookup(i => i.Grand, j => { return j.StuNo + "\t" + j.Sex; }); foreach (var item in dic) { Console.WriteLine("年級:" + item.Key); foreach (var item1 in item) { Console.WriteLine("\t\t"+ item1); } } }
輸出同樣的結果
2.鍵值對集合
SortedList<TKey, TValue>( ) 表示根據鍵進行排序的鍵/值對的集合,而鍵基於的是相關的 IComparer<T> 實現。
SortedDictionary<TKey, TValue>() 表示根據鍵進行排序的鍵/值對的集合。
使用KeyValuePair對其進行遍歷
SortedList<int, string> sortedList = new SortedList<int, string>(); foreach (Value val in enumValues) { sortedList.Add(Convert.ToInt32(val.EnumValueIndex), val.EnumValueName); } foreach (KeyValuePair<int, string> e in sortedList) { string strName = e.Value; SelectListItem myli = new SelectListItem { Text = strName, Value = e.Key.ToString(), Selected = (e.Key == value) }; cpType.Add(myli); }