質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.48%
GROUP BY

GROUP BYとはSQL文のひとつで、SELECT文において特定の列の値が等しい行ごとに表をグループ化します。

C#

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

LINQ

LINQとはLanguage INtegrated Queryの略で、「統合言語クエリ」という意味です。C#やVisual Basicといった言語のコード内に記述することができるクエリです。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

2回答

2980閲覧

c# list<object[]>の操作

taaaaaa6

総合スコア9

GROUP BY

GROUP BYとはSQL文のひとつで、SELECT文において特定の列の値が等しい行ごとに表をグループ化します。

C#

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

LINQ

LINQとはLanguage INtegrated Queryの略で、「統合言語クエリ」という意味です。C#やVisual Basicといった言語のコード内に記述することができるクエリです。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2020/08/27 04:35

前提・実現したいこと

listの中に配列を格納し、それをlinqで抽出したいと思います。
しかしlinqの使い方がわからずに困っています。
最終的に1列目をグループ化して各列を合計したいです。

ご教示をお願いします。

該当のソースコード

C#

1var result = new List<object[]>(); 2result.add( new object[] { "aaa", 1, 2, 3 } ); 3result.add( new object[] { "bbb", 2, 3, 4 } ); 4result.add( new object[] { "aaa", 3, 4, 5 } ); 5 6var query = result.Select(x => x.GroupBy(row => row(ここで1列目を指定したい 7                          8                  .Select(row => new { (1列目, 2列目, 3列目, 4列目) }));

試したこと

ここに問題に対して試したことを記載してください。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

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

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

Zuishin

2020/08/27 04:46

それを object の配列にするのがそもそもおかしいです。クラスを作りましょう。最低でも匿名クラス。
退会済みユーザー

退会済みユーザー

2020/08/27 05:03

List<T> で T はあなたが定義するカスタムクラスにしてください。他に正解はないと思います。
taaaaaa6

2020/08/27 05:07

お二人ともありがとうございます。匿名クラスとカスタムクラスを調べてみます。
Zuishin

2020/08/27 05:10

匿名クラスは「最低でも」です。匿名でない方が良いと思います。 また、「調べてみます」と言うなら本当に調べてください。調べる気がない時にその言葉を使う人が多いので、そのように見えてイラッとします。
taaaaaa6

2020/08/27 05:16

どちらも知らなかったので調べています。 不快にさせてしまい申し訳ないです。。
Zuishin

2020/08/27 05:20

どうも邪推だったようですね。 匿名クラスは調べなくていいです。匿名クラスはカスタム(自作)クラスを作るのが面倒な場合に手軽にクラスを作れる方法ですが、この場合は匿名でない自作クラスの方がおすすめです。
退会済みユーザー

退会済みユーザー

2020/08/27 06:16

https://teratail.com/questions/287115 ← このスレッドの私の回答で Country クラスが上のコメントで私が言ったカスタムクラスに該当します。List<T> の T が Country に該当します。質問者さんは自分のケースに合わせて自分の T を定義してみてください。
taaaaaa6

2020/08/31 03:01

お二人のおかげで匿名クラス、カスタムクラスが使えるようになりました。 ありがとうございました。
guest

回答2

0

しかしlinqの使い方がわからずに困っています。

GroupByには色々なオーバーロードがあるのでやり方としては色々あるのですが、例えば簡単な例はグループ化するのに使用する値を指定するバージョンが簡単です。

https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.groupby?view=netframework-4.5#System_Linq_Enumerable_GroupBy__2_System_Collections_Generic_IEnumerable___0__System_Func___0___1__

この場合、グループ化の基準となる値を関数で指定する形になります。

C#

1var result = new List<object[]>(); 2result.Add(new object[] { "aaa", 1, 2, 3 }); 3result.Add(new object[] { "bbb", 2, 3, 4 }); 4result.Add(new object[] { "aaa", 3, 4, 5 }); 5 6var groupValues = result.GroupBy(x => (string)x[0]);

イメージ説明
このようにするとオブジェクト配列の0番目が"aaa"と"bbb"の2グループのデータが出来上がります。

これであとは各グループ単位に集計すれば求めてる結果が得られると思います。

例1:計算回数を度外視してシンプルに記述

C#

1var sumValues = result 2 .GroupBy(x => (string)x[0]) 3 .Select(x => new object[] { 4 x.Key, 5 x.Sum(y => (int)y[1]), 6 x.Sum(y => (int)y[2]), 7 x.Sum(y => (int)y[3]), 8 }) 9;

例2:計算回数を抑えて記述

C#

1var sumValues = result 2 .GroupBy(x => (string)x[0]) 3 .Select(x => { 4 5 var values = new object[4]; 6 7 values[0] = x.Key; 8 values[1] = 0; 9 values[2] = 0; 10 values[3] = 0; 11 12 foreach (var obj in x) { 13 values[1] = (int)values[1] + (int)obj[1]; 14 values[2] = (int)values[2] + (int)obj[2]; 15 values[3] = (int)values[3] + (int)obj[3]; 16 } 17 18 return values; 19 }) 20;

例3:計算回数を抑えつつ、結果に匿名クラスを使用

C#

1var sumValues3 = result 2 .GroupBy(x => (string)x[0]) 3 .Select(x => { 4 5 var result = new { Key = x.Key, SumValues = new int[3] }; 6 7 foreach (var obj in x) { 8 result.SumValues[0] += (int)obj[1]; 9 result.SumValues[1] += (int)obj[2]; 10 result.SumValues[2] += (int)obj[3]; 11 } 12 13 return result; 14 }) 15;

投稿2020/08/28 04:51

dekaaki

総合スコア292

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

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

taaaaaa6

2020/08/31 03:06

わざわざobject配列に合わせてコードを書いていただきありがとうございます。 linqへの理解が深まりました。
guest

0

ベストアンサー

こんな感じで理解できるのではないかと思います。

C#

1 private class test 2 { 3 public string col1 { get; set; } 4 public int col2 { get; set; } 5 public int col3 { get; set; } 6 public int col4 { get; set; } 7 public override string ToString() 8 { 9 return string.Format($"[col1={col1}, col2={col2}, col3={col3}, col4={col4}]"); 10 } 11 } 12 13 private void test01() 14 { 15 var result = new List<test>(); 16 result.Add(new test { col1 = "aaa", col2 = 1, col3 = 2, col4 = 3 }); 17 result.Add(new test { col1 = "bbb", col2 = 2, col3 = 3, col4 = 4 }); 18 result.Add(new test { col1 = "aaa", col2 = 3, col3 = 4, col4 = 5 }); 19 20 System.Diagnostics.Debug.WriteLine("==col1でグループ化して各項目を合計=="); 21 var query1 = result 22 .GroupBy(g => g.col1) 23 .Select(g => new test { 24 col1 = g.Key, 25 col2 = g.Sum(d => d.col2), 26 col3 = g.Sum(d => d.col3), 27 col4 = g.Sum(d => d.col4) 28 }); 29 foreach(var g in query1) 30 { 31 System.Diagnostics.Debug.WriteLine(g); 32 } 33 34 System.Diagnostics.Debug.WriteLine("==この結果を見ると理解しやすいです=="); 35 var query2 = result 36 .GroupBy(g => g.col1); 37 foreach (var g in query2) 38 { 39 System.Diagnostics.Debug.WriteLine(g.Key); 40 foreach (var d in g) 41 { 42 System.Diagnostics.Debug.WriteLine(d); 43 } 44 } 45 }

投稿2020/08/28 01:48

kikukiku

総合スコア514

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

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

taaaaaa6

2020/08/31 03:03

selectの中で合計をするといいのですね。 求めていた結果を得ることができました、ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問