koshira
@koshira

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

2重foreachをLINQで書けるのか

Q&A

Closed

2重foreachをLINQを使って書けるのかが知りたいです

いろいろ試してみましたがうまく行く方法が見つかりませんでした。
2重ということでSelectManyを試してみたのですが、出力をしておしまいのものが多く、今回やりたい変数の取得がうまく行きませんでした。
Where、Selectを組み合わせてできないかも試しましたがうまく行かず、慣れていないのも事実であったためできるのであれば動いているものを見て学習したいと考え質問させていただきました。

よろしくおねがいいたします。

該当するソースコード

// 受け取り変数
int receiveImportantData;

Hoge hoge = new();

foreach(var fuga in hoge.fugaList)
{
	foreach(var num in fuga.nums)
	{
		if(num == 3)
		{
			// これがしたい。2重foreachならできる
			receiveImportantData = fuga.importantData;
		}
	}
}

var unionList = hoge.fugaList.SelectMany(fuga => fuga.nums);
foreach(var element in unionList)
{
	if(element == 0)
	{
		receiveImportantData = /*要素を回してないので取ってこれない*/
	}
}

public class Hoge
{
	public List<Fuga> fugaList = new();

	public Hoge()
	{
		for(int i = 0; i < 5; ++i)
		{
			Fuga fuga = new(i);
			fugaList.Add(fuga);
		}
	}
}

public class Fuga
{
	// これを抜き取りたい
	public int importantData = 100;

	public List<int> nums = new();

	public Fuga(int setNum)
	{
		for(int i = 0;  i < 5; ++i)
		{
			nums.Add(i);
		}
	}
}

0

1Answer

質問者さんのコードから生成される hoge は以下のようになります。なので、if(num == 3) の条件で取得できるのは hoge に含まれる 5 つ 全部の Fuga の importantData で値はすべて同じで 100 と言うことになります。それでいいのですか?

debug.jpg


今回のものは命名からお分かりかと思いますが、値はなんでも良いです。

質問者さんのコードから生成される hoge から if(num == 3) の条件で取得できるのは hoge に含まれる 5 つ 全部の Fuga の importantData と言うことになるので、取得するのは List<int> 型にして、linq を使うと以下のようにできます。

var result = hoge.fugaList
             .SelectMany(f => f.nums, (f, num) => new { f.importantData, num })
             .Where(fl => fl.num == 3)
             .Select(fl => fl.importantData)
             .ToList();

結果は以下の通りです。

result.jpg

シンタックスシュガーになるかどうかは、linq にどの程度精通しているかによるということになるかと思います。

0Like

Comments

  1. @koshira

    Questioner

    ありがとうございます。
    実際に動かして確認していただけたのですね。
    先ほどのご回答をどうしたものかと帰宅中に考えていました。

    今回のものは命名からお分かりかと思いますが、値はなんでも良いです。

    LINQ、ラムダ式初心者なもので出来ることとできないことの区別が難しく、foreachではネストが深くなってしまうし、Listを使用しているということでLINQで出来るのであればシンタックスシュガーとして記述できないかといったところです。

  2. @koshira

    Questioner

    ありがとうございます。
    満足のいく結果を提示していただけました。

    やはり私は慣れていないので、読みにくいと感じてしまいます…。
    ですが、現場によっては当たり前のように使われているのかなとも感じるのでケースバイケースですね。

    私の中のLINQの可能性を広げることができたので大きな学びとなりました。
    重ねてになりますがありがとうございました。

  3. 解決したならこのスレッドはクローズしてください。

Your answer might help someone💌