配列の操作例
Linq を使って配列(コレクション)のデータを、別の形の配列に変換するサンプルです。
配列やコレクションから必要なデータを抽出して、期待する形式のコレクション等に変換することを想定した tips です。
こういった短いコードを書くときは、テストコードを sharplab.io で書くと楽だったりすると思います。
配列のデータにインデックスを追加する
まず、最初に配列に1から始まるインデックスを追加するサンプル。匿名型を使うことでシンプルに利用できるようになりました。この形から少しずつデータの形を変えていきたいと思います。
var sources = new int[] { 1,2,3,4,1,2,3,4,1,4,2,4 }; var indexed = sources.Select((val, index) => new { val, index }); foreach (var source in indexed) { Console.WriteLine(source); }
{ val = 1, index = 0 } { val = 2, index = 1 } { val = 3, index = 2 } { val = 4, index = 3 } { val = 1, index = 4 } { val = 2, index = 5 } { val = 3, index = 6 } { val = 4, index = 7 } { val = 1, index = 8 } { val = 4, index = 9 } { val = 2, index = 10 } { val = 4, index = 11 }
条件に合ったデータだけを取得する
3より大きい数字のデータを取得します。このとき、インデックスを工夫してグルーピングしやすい groupNo
を持たせてみました。
var sources = new int[] { 1,2,3,4,1,2,3,4,1,4,2,4 }; var samples = sources.Select((val, index) => new { val, index }) .Where(p => p.val >= 3) .Select((val, groupNo) => new { val.val, groupNo = val.index - groupNo }); foreach (var source in samples) { Console.WriteLine(source); }
{ val = 3, groupNo = 2 } { val = 4, groupNo = 2 } { val = 3, groupNo = 4 } { val = 4, groupNo = 4 } { val = 4, groupNo = 5 } { val = 4, groupNo = 6 }
条件にあったデータをグルーピングする
前の条件で用意しておいた groupNo
で、二次元配列の形に変換しました。いわゆるジャンケンの連勝数を数えるような条件です。
意外とこの形に変換できると便利だったりするのでメモ。
var sources = new int[] { 1,2,3,4,1,2,3,4,1,4,2,4 }; var samples = sources.Select((val, index) => new { val, index }) .Where(p => p.val >= 3) .Select((val, groupNo) => new { val.val, groupNo = val.index - groupNo }) .GroupBy(p => p.groupNo, p => p.val); foreach (var groupData in samples) { foreach (var source in groupData) { Console.WriteLine(source); } Console.WriteLine("--"); }
3 4 -- 3 4 -- 4 -- 4 --
二次元配列を一次元配列に変換する(元に戻す)
Enumerable.SelectMany メソッドを利用することで、コレクションを1つのシーケンスの平坦な状態に戻すことができます。
var samples = sources.Select((val, index) => new { val, index }) .Where(p => p.val >= 3) .Select((val, groupNo) => new { val.val, groupNo = val.index - groupNo }) .GroupBy(p => p.groupNo, p => p.val); var array = samples.SelectMany(p => p).ToArray(); foreach (var data in array) { Console.WriteLine(data); }
3 4 3 4 4 4
参考
LINQ Pocket Reference: Learn and Implement LINQ for .NET Applications (Pocket Reference (O'Reilly))
- 作者:Albahari, Joseph,Albahari, Ben
- 発売日: 2008/03/07
- メディア: ペーパーバック
- 作者:Paolo Pialorsi;Marco Russo
- 発売日: 2014/07/02
- メディア: Kindle版