.NET 6であれば、Chunk
が使えて直観的かと思います。
Enumerable.Chunk<TSource>(IEnumerable<TSource>, Int32) メソッド (System.Linq) | Microsoft Docs
cs
1 using System . Data ;
2
3
4 var csvDataTable = new DataTable ( ) ;
5
6 csvDataTable . Columns . Add ( "ColumnA" , typeof ( int ) ) ;
7 csvDataTable . Columns . Add ( "ColumnB" , typeof ( int ) ) ;
8 csvDataTable . Columns . Add ( "ColumnC" , typeof ( string ) ) ;
9
10 csvDataTable . Rows . Add ( 1 , 10 , "A" ) ;
11 csvDataTable . Rows . Add ( 2 , 15 , "C" ) ;
12 csvDataTable . Rows . Add ( 3 , 20 , "E" ) ;
13 csvDataTable . Rows . Add ( 4 , 30 , "D" ) ;
14 csvDataTable . Rows . Add ( 5 , 50 , "K" ) ;
15
16 csvDataTable . Rows . Add ( 6 , 20 , "A" ) ;
17 csvDataTable . Rows . Add ( 7 , 30 , "A" ) ;
18 csvDataTable . Rows . Add ( 8 , 20 , "F" ) ;
19 csvDataTable . Rows . Add ( 9 , 10 , "S" ) ;
20 csvDataTable . Rows . Add ( 10 , 4 , "F" ) ;
21
22 csvDataTable . Rows . Add ( 11 , 3 , "A" ) ;
23 csvDataTable . Rows . Add ( 12 , 50 , "W" ) ;
24 csvDataTable . Rows . Add ( 13 , 120 , "A" ) ;
25 csvDataTable . Rows . Add ( 14 , 1 , "A" ) ;
26 csvDataTable . Rows . Add ( 15 , 5 , "F" ) ;
27
28 csvDataTable . Rows . Add ( 16 , 30 , "C" ) ;
29 csvDataTable . Rows . Add ( 17 , 10 , "S" ) ;
30 csvDataTable . Rows . Add ( 18 , 10 , "E" ) ;
31 csvDataTable . Rows . Add ( 19 , 5 , "R" ) ;
32 csvDataTable . Rows . Add ( 20 , 6 , "W" ) ;
33
34 csvDataTable . Rows . Add ( 21 , 4 , "A" ) ;
35 csvDataTable . Rows . Add ( 22 , 5 , "F" ) ;
36 csvDataTable . Rows . Add ( 23 , 7 , "R" ) ;
37 csvDataTable . Rows . Add ( 24 , 4 , "D" ) ;
38 csvDataTable . Rows . Add ( 25 , 2 , "W" ) ;
39
40
41 foreach ( var chunk in csvDataTable . AsEnumerable ( ) . Chunk ( 5 ) )
42 {
43 // chunkはDataRow[5]になっている(割り切れなかった場合は最後は5より少ない)
44 var start = chunk . First ( ) [ 0 ] ;
45 var end = chunk . Last ( ) [ 0 ] ;
46 var sum = chunk . Sum ( row => ( int ) row [ 1 ] ) ;
47 var countA = chunk . Count ( row => ( string ) row [ 2 ] == "A" ) ;
48
49 Console . WriteLine ( $"ColumnAが { start } ~ { end } の間、ColumnBの合計: { sum } ColumnCのAの数: { countA } " ) ;
50 }
.NET Framework等Chunk
が使えなければ、自作することも可能です。
【C#】LINQ でコレクションをN個ずつの要素に分割する - Qiita
cs
1 using System ;
2 using System . Collections . Generic ;
3 using System . Data ;
4 using System . Linq ;
5
6 namespace Qidpt2c90l7c0vo
7 {
8 class Program
9 {
10 static void Main ( )
11 {
12 var csvDataTable = new DataTable ( ) ;
13
14 csvDataTable . Columns . Add ( "ColumnA" , typeof ( int ) ) ;
15 csvDataTable . Columns . Add ( "ColumnB" , typeof ( int ) ) ;
16 csvDataTable . Columns . Add ( "ColumnC" ) ;
17
18 csvDataTable . Rows . Add ( 1 , 10 , "A" ) ;
19 csvDataTable . Rows . Add ( 2 , 15 , "C" ) ;
20 csvDataTable . Rows . Add ( 3 , 20 , "E" ) ;
21 csvDataTable . Rows . Add ( 4 , 30 , "D" ) ;
22 csvDataTable . Rows . Add ( 5 , 50 , "K" ) ;
23
24 csvDataTable . Rows . Add ( 6 , 20 , "A" ) ;
25 csvDataTable . Rows . Add ( 7 , 30 , "A" ) ;
26 csvDataTable . Rows . Add ( 8 , 20 , "F" ) ;
27 csvDataTable . Rows . Add ( 9 , 10 , "S" ) ;
28 csvDataTable . Rows . Add ( 10 , 4 , "F" ) ;
29
30 csvDataTable . Rows . Add ( 11 , 3 , "A" ) ;
31 csvDataTable . Rows . Add ( 12 , 50 , "W" ) ;
32 csvDataTable . Rows . Add ( 13 , 120 , "A" ) ;
33 csvDataTable . Rows . Add ( 14 , 1 , "A" ) ;
34 csvDataTable . Rows . Add ( 15 , 5 , "F" ) ;
35
36 csvDataTable . Rows . Add ( 16 , 30 , "C" ) ;
37 csvDataTable . Rows . Add ( 17 , 10 , "S" ) ;
38 csvDataTable . Rows . Add ( 18 , 10 , "E" ) ;
39 csvDataTable . Rows . Add ( 19 , 5 , "R" ) ;
40 csvDataTable . Rows . Add ( 20 , 6 , "W" ) ;
41
42 csvDataTable . Rows . Add ( 21 , 4 , "A" ) ;
43 csvDataTable . Rows . Add ( 22 , 5 , "F" ) ;
44 csvDataTable . Rows . Add ( 23 , 7 , "R" ) ;
45 csvDataTable . Rows . Add ( 24 , 4 , "D" ) ;
46 csvDataTable . Rows . Add ( 25 , 2 , "W" ) ;
47
48
49 foreach ( var chunk in csvDataTable . AsEnumerable ( ) . Chunk ( 5 ) )
50 {
51 // chunkはDataRow[5]になっている(割り切れなかった場合は最後は5より少ない)
52 var start = chunk . First ( ) [ 0 ] ;
53 var end = chunk . Last ( ) [ 0 ] ;
54 var sum = chunk . Sum ( row => ( int ) row [ 1 ] ) ;
55 var countA = chunk . Count ( row => ( string ) row [ 2 ] == "A" ) ;
56
57 Console . WriteLine ( $"ColumnAが { start } ~ { end } の間、ColumnBの合計: { sum } ColumnCのAの数: { countA } " ) ;
58 }
59
60 // ColumnAが順番通りならGroupByでもいいけど、ちょっとわかりにくい
61 //foreach (var chunk in csvDataTable.AsEnumerable().GroupBy(x => ((int)x[0] - 1) / 5))
62 //{
63 // var start = chunk.First()[0];
64 // var end = chunk.Last()[0];
65 // var sum = chunk.Sum(row => (int)row[1]);
66 // var countA = chunk.Count(row => (string)row[2] == "A");
67
68 // Console.WriteLine($"ColumnAが{start}~{end}の間、ColumnBの合計:{sum} ColumnCのAの数:{countA}");
69 //}
70
71 Console . ReadKey ( ) ;
72 }
73 }
74
75 // [【C#】LINQ でコレクションをN個ずつの要素に分割する - Qiita](https://qiita.com/Nossa/items/db9bff2390291432d138)
76 static class Extentions
77 {
78 public static IEnumerable < IEnumerable < T > > Chunk < T > ( this IEnumerable < T > source , int chunkSize )
79 {
80 if ( chunkSize <= 0 ) throw new ArgumentException ( "Chunk size must be greater than 0." , nameof ( chunkSize ) ) ;
81 while ( source . Any ( ) )
82 {
83 yield return source . Take ( chunkSize ) ;
84 source = source . Skip ( chunkSize ) ;
85 }
86 }
87 }
88 }