質問するログイン新規登録
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

2回答

2082閲覧

c# DataTable で指定した条件での値取得

yasu47

総合スコア7

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

1クリップ

投稿2022/05/01 07:29

0

1

c# でDataTableを操作し始めた初心者です
下記の様な形でDataTableにDataがSetされているとき
ColumnA が 1~ 5の時
Column Bの合計の数値(10+15+20+30+50 = 125)
Column Cの Aの文字の数(1)

ColumnA が 6~ 10の時
Column Bの合計の数値(20+30+20+10+4 = 84)
Column Cの Aの文字の数(2)

ColumnA が 11~ 15の時
Column Bの合計の数値(3+50+120+1+5 = 179)
Column Cの Aの文字の数(3)

ColumnA が 16~ 20の時 (上記と同じ考え)
ColumnA が 21~ 25の時(上記と同じ考え)

を求める為の方法を教えてほしいのです。
LineQの Select,Where を使えば良いかもしれませんが
複数のColumnの条件の場合のやり方がわからないのです。

私が作っているプログラムとしては
Data Table名をcsvDataTableとします。

DataColumnCollection columns = csvDataTable.Columns;
DataRowCollection rows = csvDataTable.Rows;

for (int r = 0; r < rows.Count; r++)

ここで何か処理をいれればと思っています。


上記にこだわる必要はありませんが、アドバイスお願いします。

Column A Column B Column C
1         10 A
2         15 C
3         20 E
4         30 D
5         50 K
6         20 A
7         30 A
8         20 F
9         10 S
10         4 F
11         3 A
12        50 W
13       120 A
14         1 A
15         5 F
16        30 C
17        10 S
18        10 E
19          5 R
20         6 W
21         4 A
22         5 F
23          7 R
24          4 D
25         2 W

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2022/05/01 07:45

開発環境を書いてください。OS は何か、Visual Studio のバージョン、.NET Framework か Core のどっちかとそのバージョン。 DataTable の各列の型を書いてください。 DataTable の中身は質問に書いてる通りで固定で良いのですか? 列の増減とかは無い?
dodox86

2022/05/01 08:10

> を求める為の方法を教えてほしいのです。 > LineQの Select,Where を使えば良いかもしれませんが LineQではなくLINQです。方法と言うか、LINQに限らず、実直にループ中で判定していって計算すればよいとも思いますが、そのコードも分からない(自分では書けない)と言うことでしょうか。
guest

回答2

0

.NET 6であれば、Chunkが使えて直観的かと思います。
Enumerable.Chunk<TSource>(IEnumerable<TSource>, Int32) メソッド (System.Linq) | Microsoft Docs

cs

1using System.Data; 2 3 4var csvDataTable = new DataTable(); 5 6csvDataTable.Columns.Add("ColumnA", typeof(int)); 7csvDataTable.Columns.Add("ColumnB", typeof(int)); 8csvDataTable.Columns.Add("ColumnC", typeof(string)); 9 10csvDataTable.Rows.Add(1, 10, "A"); 11csvDataTable.Rows.Add(2, 15, "C"); 12csvDataTable.Rows.Add(3, 20, "E"); 13csvDataTable.Rows.Add(4, 30, "D"); 14csvDataTable.Rows.Add(5, 50, "K"); 15 16csvDataTable.Rows.Add(6, 20, "A"); 17csvDataTable.Rows.Add(7, 30, "A"); 18csvDataTable.Rows.Add(8, 20, "F"); 19csvDataTable.Rows.Add(9, 10, "S"); 20csvDataTable.Rows.Add(10, 4, "F"); 21 22csvDataTable.Rows.Add(11, 3, "A"); 23csvDataTable.Rows.Add(12, 50, "W"); 24csvDataTable.Rows.Add(13, 120, "A"); 25csvDataTable.Rows.Add(14, 1, "A"); 26csvDataTable.Rows.Add(15, 5, "F"); 27 28csvDataTable.Rows.Add(16, 30, "C"); 29csvDataTable.Rows.Add(17, 10, "S"); 30csvDataTable.Rows.Add(18, 10, "E"); 31csvDataTable.Rows.Add(19, 5, "R"); 32csvDataTable.Rows.Add(20, 6, "W"); 33 34csvDataTable.Rows.Add(21, 4, "A"); 35csvDataTable.Rows.Add(22, 5, "F"); 36csvDataTable.Rows.Add(23, 7, "R"); 37csvDataTable.Rows.Add(24, 4, "D"); 38csvDataTable.Rows.Add(25, 2, "W"); 39 40 41foreach (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

1using System; 2using System.Collections.Generic; 3using System.Data; 4using System.Linq; 5 6namespace 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}

投稿2022/05/01 09:43

編集2023/07/30 07:50
TN8001

総合スコア10180

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

質問のコメントに対する返事がないのでいろいろ不明ですが・・・

Linq は使わずループを回してプリミティブに処理するなら「ここで何か処理をいれればと思っています」というところで、「Column Bの合計の数値」と「Column Cの Aの文字の数」を保持する変数を必要分作り、if - else if - else を使って ColumnA の値が 1~ 5、6~ 10、11~ 15 ... 21~ 25 で処理を分けて、用意したそれぞれの変数に値を設定していってはいかが?

投稿2022/05/01 08:25

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yasu47

2022/05/01 10:36

TN8001さん、SurferOnWwwさん 返信ありがとうございます。 参考にさせて頂きます。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.30%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問