2015年3月11日

LINQ で 2 個ずつ処理

シーケンスを 2 個ないし n 個ずつ処理したい場合がたまにある。
開始時間と終了時間が 1 行毎にあるログから、実行時間を抽出するとか

標準の LINQ のみだとインデックスによるグルーピングで可能だが、コードが長くなるし、パフォーマンスを必要以上に落としている気がする。

[標準 LINQ のみの実装例]

var items = new[]{"a", "b", "c", "d", "e"};

var twoEach = items
    .Select((item, index) => new {item, index})
    .GroupBy(elem => (int)(elem.index / 2), elem => elem.item);

foreach( var each in twoEach ){
    Console.WriteLine(string.Join(",", each));
}
[結果]
a,b
c,d
e

で、拡張メソッドを自作する前にググった所、ドンピシャなものが。
Interactive Extensions (Ix-Main) の Buffer

[Interactive Extensions 使用の実装例]

var items = new[]{"a", "b", "c", "d", "e"};

var twoEach = items.Buffer(2);

foreach( var each in twoEach ){
    Console.WriteLine(string.Join(",", each));
}
※結果は上と同じ
※Buffer の戻り値は IEnumerable<IList<TSource>> なのでインデックスアクセスも可能

Interactive Extensions はどんどん使おう、という話。

0 件のコメント:

コメントを投稿