C#經典系列-鍵值對


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

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM