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

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

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

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

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

LINQ

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

Q&A

解決済

1回答

7281閲覧

LINQで2次元配列で条件に合う要素の配列の1次元目のインデックスの取得。

退会済みユーザー

退会済みユーザー

総合スコア0

C#

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

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

LINQ

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

0グッド

0クリップ

投稿2019/02/01 17:02

前提・実現したいこと

下記のような2次元配列があったとして、

C#

1 var cells = new int[,] 2 { 3 { 0, 0, 0}, 4 { 0, 0, 0}, 5 { 1, 1, 0}, 6 { 0, 0, 0}, 7 { 1, 1 1}, 8 };

この要素の配列の中で、全て0の要素で埋まっている配列の1次元目のインデックスをLINQで取得する方法ってありますか?

C#

1 var cells = new int[,] 2 { 3 { 0, 0, 0}, //この1次元目のインデックス:0 4 { 0, 0, 0}, //この1次元目のインデックス:1 5 { 1, 1, 0}, 6 { 0, 0, 0}, //この1次元目のインデックス:3 7 { 1, 1 1}, 8 };

今回の例ですと、インデックス0, 1, 3を取得(細かく言えば、0, 1, 3を要素にした配列を取得)できるようなLINQです。

試したこと

「2次元配列 LINQ」で検索すると、2次元配列とLINQの相性が悪い記事が見つかったので、
もしかしたら、無理なのかもしれないと思いました。
イメージ的には、下記のようなことがしたいです。

C#

1int[] indexarr = cells.Where(i=>i.All(j => j == 0));

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

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

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

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

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

guest

回答1

0

ベストアンサー

相性が悪いというのは無理ということではなく長くなるということです。
多次元配列は色々と対応が遅れている、というより対応する気がないように見えるので、時代遅れのデータ型としてなるべく使わないのがいいと思います。
代わりにジャグ配列やリストを使いましょう。

C#

1var cells = new int[,] 2{ 3 { 0, 0, 0 }, 4 { 0, 0, 0 }, 5 { 1, 1, 0 }, 6 { 0, 0, 0 }, 7 { 1, 1, 1 }, 8}; 9var comparison = new int[] { 0, 0, 0 }; 10int[] indexarr = Enumerable 11 .Range(0, cells.GetLength(0)) 12 .Select(a => Enumerable 13 .Range(0, cells.GetLength(1)) 14 .Select(b => cells[a, b])) 15 .Select((a, i) => a.SequenceEqual(comparison) ? i : -1) 16 .Where(a => a != -1) 17 .ToArray();

追記

ジャグ配列を使った場合

C#

1var cells = new int[][] 2{ 3 new[] { 0, 0, 0 }, 4 new[] { 0, 0, 0 }, 5 new[] { 1, 1, 0 }, 6 new[] { 0, 0, 0 }, 7 new[] { 1, 1, 1 }, 8}; 9var comparison = new int[] { 0, 0, 0 }; 10int[] indexarr = cells 11 .Select((a, i) => a.SequenceEqual(comparison) ? i : -1) 12 .Where(a => a != -1) 13 .ToArray();

追記

多次元配列の別解

C#

1var cells = new int[,] 2{ 3 { 0, 0, 0 }, 4 { 0, 0, 0 }, 5 { 1, 1, 0 }, 6 { 0, 0, 0 }, 7 { 1, 1, 1 }, 8}; 9var comparison = new int[] { 0, 0, 0 }; 10int[] indexarr = cells 11 .Cast<int>() 12 .Select((value, index) => new { value, index }) 13 .GroupBy(a => a.index / cells.GetLength(1), a => a.value) 14 .Where(a => a.SequenceEqual(comparison)) 15 .Select(a => a.Key) 16 .ToArray();

追記

多次元配列の別解

C#

1var cells = new int[,] 2{ 3 { 0, 0, 0 }, 4 { 0, 0, 0 }, 5 { 1, 1, 0 }, 6 { 0, 0, 0 }, 7 { 1, 1, 1 }, 8}; 9var comparison = new int[] { 0, 0, 0 }; 10int[] indexarr = Enumerable 11 .Range(0, cells.GetLength(0)) 12 .Where(index => Enumerable 13 .Range(0, cells.GetLength(1)) 14 .Select(a => cells[index, a]) 15 .SequenceEqual(comparison)) 16 .ToArray();

投稿2019/02/01 23:02

編集2019/02/01 23:40
Zuishin

総合スコア28660

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

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

退会済みユーザー

退会済みユーザー

2019/02/02 12:26

ご回答ありがとうございます。 今回はコードを作り込んでしまったので、都合上、2次元配列を使いたいと思います。 最初にご回答いただいているコードについて、考えて理解しようとしているのですが、 2点質問があります。 ・1点目。 ~ cells[a, b])) までのコードで、cellsの2次元配列っぽいものをEnumerable型で作っているというふうに解釈しました。 これの構造(型)を知りたいのですが、 var cells = Enumerable .Range(0, cells.GetLength(0)) .Select(a => Enumerable .Range(0, cells.GetLength(1)) .Select(b => cells[a, b])); とした場合、左辺をvarじゃなく、明示的に型とかで書く場合、どういうふうに書けますか? varで書いた場合のcellsをデバッグしてみましたが、わかりませんでした。 ・2点目。 ~.Select((a, i) => a.SequenceEqual(comparison) ? i : -1) のaには、{ 0, 0, 0 }とか、 { 1, 1, 0}等の要素の配列が入り、iには、その配列の要素の1次元目のインデックスが入るものと解釈しました。 ここで、 var c = Enumerable .Range(0, cells.GetLength(0)) .Select(a => Enumerable .Range(0, cells.GetLength(1)) .Select(b => cells[a, b])) .Select((a, i) => a.SequenceEqual(comparison) ? a : new int[]{-1,-1,-1}); のように、同一のときにa(要素の配列)を返すように書いてみたのですが、 やはりこれも左辺をvarじゃなく、明示的に型とかで書く場合、どういうふうに書けますか? また、解釈していることについて間違っている点があればご指摘お願い致します。
Zuishin

2019/02/02 13:46

var をマウスカーソルでポイントしてみてください。型が表示されます。
退会済みユーザー

退会済みユーザー

2019/02/02 15:53

ご回答ありがとうございます。 両方とも、 IEnumerable<IEnumerable<int>>型で受け取ることができました。 これは、IEnumerableの中にIEnumerable<int>があるジャグ配列のようなもの(ジャグIEnumerable)ということですか?
退会済みユーザー

退会済みユーザー

2019/02/03 03:12

ご回答ありがとうございます。 ご提示のURL拝見しました。 「ジェネリック型を型引数(型パラメーター)とするジェネリック型」のご教示で理解できたつもりですが、すみません、 今回のIEnumerable<IEnumerable<int>>は、 「IEnumerable型の要素にIEnumerable<int>型が入るもの」という解釈でも合っていますか?
Zuishin

2019/02/03 03:36

要素ではなく型引数です。 また IEnumerable 型と IEnumereble<T> 型は違う型です。 ですから、合っているかいないかで言えば合っていません。 そのページだけでなく、概要から読んでみればわかるかもしれません。
Zuishin

2019/02/03 04:24

「要素が入る」という表現からそのように読みましたが、よく読んでみると 「IEnumerable<IEnumerable<int>> の要素の型は IEnumerable<int> である」という意味のようにも見えますね。そうであれば正しいです。
退会済みユーザー

退会済みユーザー

2019/02/03 05:13

ご回答ありがとうございます。 とても勉強になりました。 理解できました。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問