stackoverflowにLinqを使って、特定のシーケンスを決まった数のチャンクに分割する
コードがあったので、メモメモ。要素が多いシーケンスを相手にするときに便利です。
- Split List into Sublists with LINQ
以下、サンプルです。
#region LinqSamples-59 /// <summary> /// Linqにて、シーケンスをチャンクに分割して処理するサンプルです. /// </summary> public class LinqSamples59 : IExecutable { public void Execute() { // // 要素が10のシーケンスを2つずつのチャンクに分割. // foreach (var chunk in Enumerable.Range(1, 10).Chunk(2)) { Console.WriteLine("Chunk:"); foreach (var item in chunk) { Console.WriteLine("\t--> {0}", item); } } // // 要素が10000のシーケンスを1000ずつのチャンクに分割し // それぞれのチャンクごとにインデックスを付与. // foreach (var chunk in Enumerable.Range(1, 10000).Chunk(1000).Select((x, i) => new { Index = i, Count = x.Count() })) { Console.WriteLine(chunk); } } } public static class LinqSamples59_Extensions { /// <summary> /// シーケンスを指定されたサイズのチャンクに分割します. /// </summary> public static IEnumerable<IEnumerable<T>> Chunk<T>(this IEnumerable<T> self, int chunkSize) { if (chunkSize <= 0) { throw new ArgumentException("Chunk size must be greater than 0.", "chunkSize"); } while (self.Any()) { yield return self.Take(chunkSize); self = self.Skip(chunkSize); } } } #endregion
実行すると以下のようになります。
Chunk: --> 1 --> 2 Chunk: --> 3 --> 4 Chunk: --> 5 --> 6 Chunk: --> 7 --> 8 Chunk: --> 9 --> 10 { Index = 0, Count = 1000 } { Index = 1, Count = 1000 } { Index = 2, Count = 1000 } { Index = 3, Count = 1000 } { Index = 4, Count = 1000 } { Index = 5, Count = 1000 } { Index = 6, Count = 1000 } { Index = 7, Count = 1000 } { Index = 8, Count = 1000 } { Index = 9, Count = 1000 }
Any, Take, Skipは以前の記事にて記述していますので
よければ、ご参照ください。
- Linq入門記-42 (LINQ To Object, Any)
- Linq入門記-46 (LINQ To Object, Take, TakeWhile)
- Linq入門記-47 (LINQ To Object, Skip, SkipWhile)
- Linq入門記 目次
================================
過去の記事については、以下のページからご参照下さい。
- いろいろ備忘録日記まとめ
サンプルコードは、以下の場所で公開しています。
- いろいろ備忘録日記サンプルソース置き場