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

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

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

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

LINQ

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

Q&A

解決済

3回答

1779閲覧

階層的なオブジェクトをlinqを使い、groupbyしたい。

kaile

総合スコア3

C#

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

LINQ

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

1グッド

0クリップ

投稿2022/04/11 07:59

編集2022/04/11 10:42

以下のようなオブジェクトがありCountsを、FruitsNameでgroupbyし重複するフルーツをまとめて数を合計した結果を取得したいです。

public class CountsByFruits{  public string FruitsName; public List<CountData> Data; } public class CountData{ public string Color; public double Count; }
List<CountsByFruits> Counts = { FruitsName:"りんご", Data:{ Color:"赤", Count:3 }, { Color:"緑", Count:1 } }, { FruitsName:"さくらんぼ", Data:{ Color:"赤", Count:3 }, { Color:"緑", Count:1 }, }, { FruitsName:"りんご", Data:{ Color:"赤", Count:2 }, { Color:"緑", Count:4 } }

●取得したい結果

結果は元々のList<CountsByFruits>の形で取得したいです。 Result = { FruitsName:"りんご", Data:{ Color:"赤", Count:5 }, { Color:"緑", Count:5 } }, { FruitsName:"さくらんぼ", Data:{ Color:"赤", Count:3 }, { Color:"緑", Count:1 }, }

●試して詰まっているところ

var result = Counts.GroupBy(x => x.FruitsName).Select・・
TN8001👍を押しています

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

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

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

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

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

ozwk

2022/04/11 08:21

x.Name ? FruitsNameではなくて?
kaile

2022/04/11 08:28

ご指摘ありがとうございます。 FruitsNameの間違えでした。質問の方も修正しました。
退会済みユーザー

退会済みユーザー

2022/04/11 10:32 編集

List<CountsByFruits> オブジェクトの Counts を「FruitsNameでgroupbyし重複するフルーツをまとめて数を合計した結果」をオリジナルと同じ List<CountsByFruits> 型の Result に投射したいということですか?
kaile

2022/04/11 10:33

オリジナルと違う形でも、同じ形でもどちらでも問題ないです。
退会済みユーザー

退会済みユーザー

2022/04/11 10:36

> オリジナルと違う形でも、同じ形でもどちらでも問題ないです。 そういうのはダメです。答えてもそれじゃないと言われそうなので。結果をどういう型のオブジェクトにしたいのか、クラス定義を書いてください。
kaile

2022/04/11 10:37

承知しました。結果はオリジナルと同じ型で取得できるようにしたいです。
退会済みユーザー

退会済みユーザー

2022/04/11 11:03

要件が決まっていて、それに沿ってじっくり考えてこうしたいということを決めてるわけではなさそうですね。それでもいいのですけど、また前のスレッド https://teratail.com/questions/356450 の話と同じようなことになりそうな気がします。気のせいですか?
kaile

2022/04/11 11:11

できればオリジナルと同じ型が良かったのですが、変わってもデータを加工すればいいと考えてしまいさっきのような回答になってしまいました。 今回は、実現したいことを具体的に記載したので大丈夫だと思っています。
guest

回答3

0

ベストアンサー

入力も出力もC#コードではないし、JSONにもなってません(まあ気持ちはわかりますが^^;
試しやすい形式にしてください(回答者も実行して確認しています)

●試して詰まっているところ

凝ったLINQは分解して1段ずつ確認、foreachで展開するとわかりやすいです。
foreachでできてからLINQに直すようにします。
場合によっては無理してワンライナーにするより、そのままのほうがわかりやすい・手直しやすいこともあるでしょう。

.NET 6(C# 10)です。

cs

1using System.Text.Encodings.Web; 2using System.Text.Json; 3using System.Text.Unicode; 4 5 6List<CountsByFruits> Counts = new() 7{ 8 new() 9 { 10 FruitsName = "りんご", 11 Data = new() 12 { 13 new() { Color = "赤", Count = 3, }, 14 new() { Color = "緑", Count = 1, }, 15 }, 16 }, 17 new() 18 { 19 FruitsName = "さくらんぼ", 20 Data = new() 21 { 22 new() { Color = "赤", Count = 3, }, 23 new() { Color = "緑", Count = 1, }, 24 }, 25 }, 26 new() 27 { 28 FruitsName = "りんご", 29 Data = new() 30 { 31 new() { Color = "赤", Count = 2, }, 32 new() { Color = "緑", Count = 4, }, 33 }, 34 }, 35}; 36 37var result = Counts.GroupBy(x => x.FruitsName).Select(x => new CountsByFruits 38{ 39 FruitsName = x.Key, 40 Data = x.SelectMany(x => x.Data) 41 .GroupBy(x => x.Color) 42 .Select(x => new CountData { Color = x.Key, Count = x.Sum(x => x.Count) }) 43 .ToList(), 44}).ToList(); 45 46var options = new JsonSerializerOptions 47{ 48 Encoder = JavaScriptEncoder.Create(UnicodeRanges.All), 49 IncludeFields = true, 50 WriteIndented = true, 51}; 52Console.WriteLine(JsonSerializer.Serialize(result, options)); 53 54 55// こんなんでブレークしつつちょっとずつ確認した 56//var r = new List<CountsByFruits>(); 57//foreach (var g in Counts.GroupBy(x => x.FruitsName)) 58//{ 59// var m = g.SelectMany(x => x.Data); 60// var mm = m.GroupBy(x => x.Color); 61// var mmm = mm.Select(x => new CountData { Color = x.Key, Count = x.Sum(x => x.Count) }); 62// var f = new CountsByFruits { FruitsName = g.Key, Data = mmm.ToList(), }; 63// r.Add(f); 64//} 65//Console.WriteLine(JsonSerializer.Serialize(r, options)); 66 67 68public class CountsByFruits 69{ 70 public string FruitsName; 71 public List<CountData> Data; 72} 73public class CountData 74{ 75 public string Color; 76 public double Count; 77}

json

1[ 2 { 3 "FruitsName": "りんご", 4 "Data": [ 5 { 6 "Color": "赤", 7 "Count": 5 8 }, 9 { 10 "Color": "緑", 11 "Count": 5 12 } 13 ] 14 }, 15 { 16 "FruitsName": "さくらんぼ", 17 "Data": [ 18 { 19 "Color": "赤", 20 "Count": 3 21 }, 22 { 23 "Color": "緑", 24 "Count": 1 25 } 26 ] 27 } 28]

投稿2022/04/11 12:01

編集2023/08/15 15:34
TN8001

総合スコア9326

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

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

kaile

2022/04/11 12:27

ありがとうございます。 質問のソースコードは、きちんとしたものになってなくて申し訳ありません。今後は気を付けます。 同じように実行したところ取得したい結果を得ることができました。また、解決への導き方も教えてくださりありがとうございます。参考にさせていただきます。 ありがとうございました。
guest

0

Linqだけで考えるとややこしい構造なので、泥臭くやってみました。
要件は満たしているはず…

cs

1var result = new List<CountsByFruits>(); 2foreach (var group in Counts.GroupBy(x => x.FruitsName)) 3{ 4 var dstCountsByFruits = new CountsByFruits 5 { 6 FruitsName = group.Key, 7 Data = new List<CountData>() 8 }; 9 foreach (CountsByFruits counts in group) 10 { 11 foreach (CountData count in counts.Data) 12 { 13 var foundedCountData = dstCountsByFruits.Data 14 .FirstOrDefault(x => x.Color == count.Color); 15 if (foundedCountData == null) 16 { 17 var dstCountData = new CountData 18 { 19 Color = count.Color, 20 Count = count.Count 21 }; 22 dstCountsByFruits.Data.Add(dstCountData); 23 } 24 else 25 { 26 foundedCountData.Count += count.Count; 27 } 28 } 29 } 30 result.Add(dstCountsByFruits); 31} 32

投稿2022/04/11 12:56

KomoriGameDev

総合スコア433

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

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

kaile

2022/04/12 00:01

ありがとうございます。<(_ _)>
guest

0

投稿2022/04/11 10:40

5ugarVVatch1ng

総合スコア356

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

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

kaile

2022/04/11 11:01

ご回答ありがとうございます。 合計値を出す値が、groupbyする値とは違う階層になるので以下の箇所を少し変えないと難しいと感じます。 A = x.Sum(d => d.A)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問