C#ではEnumerable.ToLookup
(LINQ)を使うことで配列やリスト(IEnumerable
)を条件ごとに分類できます。ToDictionary
と組み合わせることで辞書も作成できます。
模式図: Enumerable.ToLookup:■□■□○ → ■■、□□、○ ■□○:分類された要素(キーセレクタが同じキーを返す要素)
Enumerable.ToLookup
の例
Enumerable.ToLookup
のサンプルコードです。
整数配列を3
で割った余りで分類する。
using System.Linq; var intArray1 = new[] { 0, 1, 2, 3, 4, 5, 6 }; var lookup1 = intArray1.ToLookup( i => i % 3, // keySelector i => i); // valueSelector // lookup1[0]: {0, 3, 6} // lookup1[1]: {1, 4} // lookup1[2]: {2, 5} var item0 = lookup1[0].ToArray(); // {0, 3, 6}
C# 8
using System.Linq; class Program { static void Main() { var intArray1 = new[] { 0, 1, 2, 3, 4, 5, 6 }; var lookup1 = intArray1.ToLookup( i => i % 3, // keySelector i => i); // valueSelector // lookup1[0]: {0, 3, 6} // lookup1[1]: {1, 4} // lookup1[2]: {2, 5} var item0 = lookup1[0].ToArray(); // {0, 3, 6} } }
文字列配列を最後の文字の大文字で分類して末尾に'0'
をつける。
using System.Linq; var strArray1 = new[] { "abc", "def", "gfc", "aaa", "ccc" }; var lookup1 = strArray1.ToLookup( s => char.ToUpper(s.TakeLast(1).ElementAt(0)), s => s + '0'); // lookup1['C']: {"abc0", "gfc0", "ccc0"} // lookup1['F']: {"def0"} // lookup1['A']: {"aaa0"} var itemc = lookup1['c'].ToArray(); // {} var itemC = lookup1['C'].ToArray(); // {"abc0", "gfc0", "ccc0"} strArray1[0] = "ppppp"; // lookup1の内容は変わりません。
C# 8
using System.Linq; class Program { static void Main() { var strArray1 = new[] { "abc", "def", "gfc", "aaa", "ccc" }; var lookup1 = strArray1.ToLookup( s => char.ToUpper(s.TakeLast(1).ElementAt(0)), s => s + '0'); // lookup1['C']: {"abc0", "gfc0", "ccc0"} // lookup1['F']: {"def0"} // lookup1['A']: {"aaa0"} var itemc = lookup1['c'].ToArray(); // {} var itemC = lookup1['C'].ToArray(); // {"abc0", "gfc0", "ccc0"} strArray1[0] = "ppppp"; // lookup1の内容は変わりません。 } }
文字列配列を末尾が'c'
かどうかで分類して先頭の2文字にする。
using System.Linq; var strArray1 = new[] { "abc", "def", "gfc", "aaa", "ccc" }; var lookup1 = strArray1.ToLookup( key => key.EndsWith('c'), el => el.Substring(0, 2)); // lookup1[true]: {"ab", "gf", "cc"} // lookup1[false]: {"de", "aa"} var item0 = lookup1[false].ToArray(); // {"de", "aa"}
C# 8
using System.Linq; class Program { static void Main() { var strArray1 = new[] { "abc", "def", "gfc", "aaa", "ccc" }; var lookup1 = strArray1.ToLookup( key => key.EndsWith('c'), el => el.Substring(0, 2)); // lookup1[true]: {"ab", "gf", "cc"} // lookup1[false]: {"de", "aa"} var item0 = lookup1[false].ToArray(); // {"de", "aa"} } }
Enumerable.ToLookupとEnumerable.ToDictionaryの組み合わせ
Enumerable.ToLookup
で得られるILookup
にEnumerable.ToDictionary
を適用して配列やリストの辞書を作成できます。ILookup.ToDictionary
はIGrouping
が渡されるので、IGrouping.Key
でキー、IGrouping.ToArray
やIGrouping.ToList
で配列やリストの値を指定しています。
using System.Linq; var intArray1 = new[] { 0, 1, 2, 3, 4, 5, 6 }; // 値が配列の辞書を作成する。 var dict1 = intArray1.ToLookup( key => key % 3, el => el) .ToDictionary(key => key.Key, el => el.ToArray()); // [0]: int[3] {0, 3, 6} // [1]: int[2] {1, 4} // [2]: int[2] {2, 5} // 値がリストの辞書を作成する。 var dict2 = intArray1.ToLookup( key => key % 3, el => el) .ToDictionary(key => key.Key, el => el.ToList()); // [0]: List<int> {0, 3, 6} // [1]: List<int> {1, 4} // [2]: List<int> {2, 5}
C# 8
using System.Linq; class Program { static void Main() { var intArray1 = new[] { 0, 1, 2, 3, 4, 5, 6 }; // 値が配列の辞書を作成する。 var dict1 = intArray1.ToLookup( key => key % 3, el => el) .ToDictionary(key => key.Key, el => el.ToArray()); // [0]: int[3] {0, 3, 6} // [1]: int[2] {1, 4} // [2]: int[2] {2, 5} // 値がリストの辞書を作成する。 var dict2 = intArray1.ToLookup( key => key % 3, el => el) .ToDictionary(key => key.Key, el => el.ToList()); // [0]: List<int> {0, 3, 6} // [1]: List<int> {1, 4} // [2]: List<int> {2, 5} } }