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

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

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

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

LINQ

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

Q&A

解決済

3回答

3984閲覧

[c#]LINQを使って2次元配列からランダムな要素のインデックスを得るには

celeritas

総合スコア11

C#

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

LINQ

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

0グッド

0クリップ

投稿2018/03/23 09:27

c#において次のようなint型の2次元配列があるとします。
この配列は「0」もしくは「1」を値として格納しています。

c#

1var data = new[,] 2{ 3 {0,1,1,0,0,1}, 4 {1,0,1,0,1,1}, 5 ...中略... 6}; 7 8Console.WriteLine( data[x,y] ); // 0 or 1

LINQを使って値が0の要素をランダムに1つ取得し、
そのインデックスx,yを得るにはどのようにすればよいでしょうか。

ご教授のほど宜しくお願いいたします。

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

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

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

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

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

guest

回答3

0

ベストアンサー

csharp

1var value = data.Cast<int>() //1次元配列に戻す 2 .Select((d, i) => new { X = i % data.GetLength(1), Y = i / data.GetLength(1), Value = d }) //index付きSelectでx,yと値取得 3 .Where(t => t.Value == 0) //値が0の物のみ抽出 4 .OrderBy(_ => Guid.NewGuid()) //ランダムな値でソート 5 .First(); //最初の一つ(匿名クラス{X, Y, Value}型です。) 6 7Console.WriteLine($"x:{value.X} y:{value.Y}");

こんな感じですかね?
ところでX,Yと言っていますが、
data[x,y]とするとコード上の見た目のX座標とY座標が逆転するので注意してください。
上記コードは見た目のX,Yに合わせてます。
逆が良ければGetLength(1)を2か所ともGetLength(0)にしてください。

投稿2018/03/23 10:43

sh_akira

総合スコア380

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

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

celeritas

2018/03/23 11:23

こんな解決法があるとは思いませんでした! まだ知らない構文ばかりを検索していましたが、 数学的なアプローチで解決できるという点に感動しました!
guest

0

以下で { X, Y, Value } の匿名クラスのリストができます。
何を言っているかわからなければとりあえずコンソールアプリを作って実行してみればわかります。

C#

1var list = Enumerable 2 .Range(data.GetLowerBound(0), data.GetUpperBound(0) + 1) 3 .SelectMany(x => 4 { 5 return Enumerable 6 .Range(data.GetLowerBound(1), data.GetUpperBound(1) + 1) 7 .Select(y => new { X = x, Y = y, Value = data[x, y] }); 8 }) 9 .ToList(); 10foreach (var i in list) Console.WriteLine(i);

ここから Value が 0 のものを選び出してリスト化し、その要素数以内の乱数で要素を選んだらいいでしょう。

投稿2018/03/23 10:35

編集2018/03/23 10:38
Zuishin

総合スコア28660

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

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

0

うまいこと、(x,y)=>value の形のDictonaryに変換して、

where(n=> n.value == 0).OrderBy( x => Guid.NewGuid( ) ).first

する

投稿2018/03/23 09:37

kiichi54321

総合スコア1984

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問