🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
foreach

foreachは、List・Collection・Arrayといったデータ構造の各要素に対して繰り返し処理を実行するために扱われる、制御構造の構文です。

C#

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

ループ

ループとは、プログラミングにおいて、条件に合致している間、複数回繰り返し実行される箇所や、その制御構造を指します

Q&A

解決済

1回答

2015閲覧

結合後の値にグループ化した値を反映させるには

AEGIL

総合スコア7

foreach

foreachは、List・Collection・Arrayといったデータ構造の各要素に対して繰り返し処理を実行するために扱われる、制御構造の構文です。

C#

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

ループ

ループとは、プログラミングにおいて、条件に合致している間、複数回繰り返し実行される箇所や、その制御構造を指します

0グッド

0クリップ

投稿2020/12/23 04:48

編集2020/12/24 01:06

名前の行が一致しているときに枝番にしたいのですが、枝番号の列が1を羅列するだけのものになってしまいます。
この場合ループの処理がうまくいっていないことが原因なのでしょうか?
処理がどこでおかしくなっているのか教えていただきたいです。

c#

1 2public class OracleDT //こちら追記 3 { 4   //格納先 5 public string name{ get; set; } 6 public int count{ get; set; } 7 public string code{ get; set; } 8 } 9 public class CsvDT 10 { 11   //格納先 12 public string name{ get; set; } 13 public int count{ get; set; } 14 public string code{ get; set; }//書き漏らし追記 15 } 16 public class ResultDT 17 { 18 19   //格納先 20 public string NO{ get; set; } 21 public string 名前{ get; set; } 22 public int 枝番号{ get; set; } 23 24 }

c#

1 List<OracleDT> oracleDTs = createOracleList(); 2 List<CsvDT> csvDTs = createCsvList(); 3 int i++; 4 var innnerjoin = from c in csvDTs 5 join o in oracleDTs 6 on c.code equals o.code 7 8 select new ResultDT 9 { 10 NO = i++, 11 名前 = c.Name, 12 枝番号 = 1,//c.countだと全体に対しての連番になってしまう 13 14 }; 15 // 対象でグルーピングして、2件以上なら抽出 16 var num = innnerjoin.GroupBy(key=>key.名前).Where(over => over.Count()>1); 17 foreach(var data in num) 18 { 19 // インデックス付与 20 var groupData = csvDTs.Select((g, index) => new {csvDTs = g,index=index}); 21 foreach (var sub in groupData) 22 { 23 sub.csvDTs.count = sub.index; 24 25 } 26 27 } 28

以下追記
今の状態

No,名前,枝番 1,satou,1 2,satou,1 3,kagaya,1 4,gotou,1 5,gotou,1 6,gotou,1

最終的にこういうものを表示したい。

No,名前,枝番 1,satou,1 2,satou,2 3,kagaya,1 4,gotou,1 5,gotou,2 6,gotou,3

追記
for(ResultDT item in innnerjoin)
{
Console.WriteLine(item.名前);//データ(satou) 
Console.WriteLine(item.枝番);//データ(1)
}
補足説明
質問に書いてある「今の状態」 var innnerjoin = ... のコードで取得した innnerjoin の内容が上記の追記に記載してあるようにforeach(ResultDT item in innnerjoin){ }のループの状態になります。
それをコード内の
>> // 対象でグルーピングして、2件以上なら抽出
var num =....以降のコードで「最終的にこういうものを表示したい」に記載している枝番号列の状態にしたいと考えています。

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2020/12/23 05:29 編集

innnerjoin に取得できるものが分かりません。サンプルで良いので具体的にそれを書いて、var num = ... 以下のコードで期待する結果が何で、現状それがどのように期待と異なるかを書いてください。
退会済みユーザー

退会済みユーザー

2020/12/23 05:41

期待する結果だけ書いてもらってもダメです。 上に書きましたが innnerjoin に取得できるものが分かりません。サンプルで良いので var innnerjoin = ... 以下のコードで取得できるものを具体的に書いて、var num = ... 以下のコードで現状それがどのように期待と異なるかを書いてください。
AEGIL

2020/12/23 05:45

すみません書き漏らしていたので改めて現状の状態を記入したのですが、 質問に質問で返してしまって申し訳ないのですが、innnerjoinに取得できるものがわからないというのは何を指しているのでしょうか?すみませんがよろしくお願いします。
退会済みユーザー

退会済みユーザー

2020/12/23 05:50

var innnerjoin = ... で ResultDT のコレクションを取得しているようですが、その中身が分からないと話にならないと言っているのです。 もし、現状、枝番が全部 1 になるのが問題と言っているなら、 ... select new ResultDT { NO = i++, 名前 = c.Name, 枝番号 = 1,//c.countだと全体に対しての連番になってしまう }; としているので当たり前では?
AEGIL

2020/12/23 06:16

確かに1と書いているので1が連続するのは当たり前のことですね。 仮に1ではなく、枝番号 = c.countとして行う場合、joinの部分を名前単位でループを作成してResultDTに追加という形にすることは可能でしょうか。
退会済みユーザー

退会済みユーザー

2020/12/23 07:07

何を言っているのか分かりません。前に、 > var innnerjoin = ... で ResultDT のコレクションを取得しているようですが、その中身が分からないと話にならないと言っているのです。 と書きましたけど、聞かれたことには答えてもらわないと話は通じません。聞きたいことだけ一方的に聞いてくるのは NG です。
AEGIL

2020/12/23 07:21 編集

ウォッチ内の内容 innnerjoin={System.Linq.Enumerable.<JoinIterator>d__38<AP_Read0.Form1.CsvDT, AP_Read0.Form1.OracleDT, string, AP_Read0.Form1.ResultDT>}となっているのですがこの内容でしょうか?
AEGIL

2020/12/23 07:31

一旦、コレクションから調べなおしてみます。
AEGIL

2020/12/23 08:36

現状を整理後改めて質問させていただきます。こちら削除依頼出したほうがよろしいでしょうか?
退会済みユーザー

退会済みユーザー

2020/12/23 08:39

そうじゃなくて innnerjoin の中身です。foreach (ResultDT item in innnerjoin) でループを回して、各 ResultDT の No, 名前, 枝番がどうなっているか調べて書いてください。
退会済みユーザー

退会済みユーザー

2020/12/23 08:40

> こちら削除依頼出したほうがよろしいでしょうか? そんなことをしたらあなたは私の BL 入りです。
AEGIL

2020/12/23 08:55

何から何まで申し訳ありません。中身を見るためにはの内部はどうしたらいいのでしょうか?内部を見るということをしたことがないので教えていただきたいです。 foreach(ResultDT item in innerjoin ) { }
退会済みユーザー

退会済みユーザー

2020/12/23 09:06

それはあまりに初歩的なことですので自助努力でお願いします。そこまで聞かないと分からない、調べる努力もしないのでは、この先もう何を聞いても分からないですよ。
Zuishin

2020/12/23 13:15

group を使うのが簡単そうですが、調べるのが難しいなら無理に LINQ を使わず普通にループで行えばいいんじゃないでしょうか。
AEGIL

2020/12/23 13:29

>group を使うのが簡単そうですが、調べるのが難しいなら無理に LINQ を使わず普通にループで行えばいいんじゃないでしょうか。 確かにわからないlinqにこだわるのもよくないですね。一旦ループでやってみます。
退会済みユーザー

退会済みユーザー

2020/12/23 23:10 編集

質問に書いてある「今の状態」というのが var innnerjoin = ... のコードで取得した innnerjoin の中身 (foreach (ResultDT item in innnerjoin) でループを回して中身を見た結果と同じ) で、それを var num = ... 以下のコードで「最終的にこういうものを表示したい」に書き換えたいということですか?
AEGIL

2020/12/23 23:57

その解釈でお間違いないです。
退会済みユーザー

退会済みユーザー

2020/12/24 00:38

上記の解釈を質問欄を編集して追加情報として書いていただくようお願いします。
guest

回答1

0

ベストアンサー

確かにわからないlinqにこだわるのもよくないですね。一旦ループでやってみます。

であれば、以下のようにループを回して処理してはいかがですか。注:質問のコードの ResultDT クラスの NO が string 型というのは変ですので、以下のコードでは int 型に書き換えています。

using System; using System.Collections.Generic; using System.Linq; namespace ConsoleAppLinq { class Program { static void Main(string[] args) { List<ResultDT> innerjoin = new List<ResultDT> { new ResultDT { No = 1, 名前 = "satou", 枝番号 = 1 }, new ResultDT { No = 2, 名前 = "satou", 枝番号 = 1 }, new ResultDT { No = 3, 名前 = "kagaya", 枝番号 = 1 }, new ResultDT { No = 4, 名前 = "gotou", 枝番号 = 1 }, new ResultDT { No = 5, 名前 = "gotou", 枝番号 = 1 }, new ResultDT { No = 6, 名前 = "gotou", 枝番号 = 1 } }; foreach (ResultDT result in innerjoin) { Console.WriteLine($"No: {result.No}, 名前: {result.名前}, 枝番号: {result.枝番号}"); } Console.WriteLine("-----------------------------------"); string[] names = innerjoin.Select(r => r.名前).Distinct().ToArray(); foreach (string name in names) { List<ResultDT> resultsByName = innerjoin.Where(r => r.名前 == name).ToList(); int i = 1; foreach (ResultDT result in resultsByName) { result.枝番号 = i++; } } foreach (ResultDT result in innerjoin) { Console.WriteLine($"No: {result.No}, 名前: {result.名前}, 枝番号: {result.枝番号}"); } } } public class ResultDT { public int No { get; set; } public string 名前 { get; set; } public int 枝番号 { get; set; } } }

結果は:

イメージ説明

var innnerjoin = ... のコードで取得した innnerjoin の中身を書き換えるということのようですので、Linq で GroupBy を使ってというのはかえって面倒な気がします。 下の追記を書く前はそういう気がしたのですが、面倒ということはなかったです。分かり難いとは思いますが。

【追記】

GroupBy を使ったコードも追記しておきます。結局ループを回して処置するのですが。

Console.WriteLine("======================================="); List<ResultDT> innerjoin2 = new List<ResultDT> { new ResultDT { No = 1, 名前 = "satou", 枝番号 = 1 }, new ResultDT { No = 2, 名前 = "satou", 枝番号 = 1 }, new ResultDT { No = 3, 名前 = "kagaya", 枝番号 = 1 }, new ResultDT { No = 4, 名前 = "gotou", 枝番号 = 1 }, new ResultDT { No = 5, 名前 = "gotou", 枝番号 = 1 }, new ResultDT { No = 6, 名前 = "gotou", 枝番号 = 1 } }; foreach (ResultDT result in innerjoin2) { Console.WriteLine($"No: {result.No}, 名前: {result.名前}, 枝番号: {result.枝番号}"); } Console.WriteLine("-----------------------------------"); IEnumerable<IGrouping<string, ResultDT>> num = innerjoin2.GroupBy(r => r.名前).Where(g => g.Count() > 1); foreach (IGrouping<string, ResultDT> item in num) { int i = 1; foreach (ResultDT result in item) { result.枝番号 = i++; } } foreach (ResultDT result in innerjoin2) { Console.WriteLine($"No: {result.No}, 名前: {result.名前}, 枝番号: {result.枝番号}"); }

結果は同じです。以下の画像の ========== の下がそれです。

イメージ説明

投稿2020/12/24 01:31

編集2020/12/24 02:28
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

AEGIL

2020/12/24 03:20

ご回答ありがとうございます。 詳しく詳細まで頂きありがとうございます。 一点確認したいのですが、質問文のコードだとpublic class ResultDT>innnerjoin=oracleDTs+csvDTsという考え方だと思っていたのですが、 上記の内容をdatagridviewに書き込む際にinnnerjoinを呼び出してしまう string[] names = innerjoin..... foreach (string name in names) { } //ソース作成 BindingSource source = new BindingSource(); //ソースにinnnerjoin内のデータ挿入 source.DataSource=innnerjoin; //DataGridViewにデータを挿入 dataGridView1.DataSource = source; でinnnerjoinの内部が変わった状態で値が見えると思っていたのですが、innnerjoinには変化はなくあくまで該当データを参照しただけということなのでしょうか?
退会済みユーザー

退会済みユーザー

2020/12/24 03:45 編集

> 質問文のコードだとpublic class ResultDT>innnerjoin=oracleDTs+csvDTsという考え方だと思っていたのですが、 意味が分かりません。ここに書いてあること以外は知り得ない第三者が読んで分かるように書いてください。 > 上記の内容をdatagridviewに書き込む際にinnnerjoinを呼び出してしまう DataGridView と正しく書いてください。文章も日本語的に変です。いろいろイイカゲンすぎ。きちんと細心の注意を払って書きましょう。 DataGridView の話は初めて出てきましたが、一つの問題の解決が次の疑問を呼んで、次から次へと質問を繰り返えすというのは止めてください。このスレッドの課題は解決しているはずですのでクローズしてください。DataGridView の話は別に新たにスレッドを立てて質問してください。
AEGIL

2020/12/24 03:43

そうですね。DataGridViewの記述含め申し訳ありません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問