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

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

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

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

Unity

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

Q&A

解決済

1回答

5031閲覧

if文に配列の要素を複数指定する方法

退会済みユーザー

退会済みユーザー

総合スコア0

C#

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

Unity

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

0グッド

0クリップ

投稿2020/05/18 07:41

編集2020/05/20 14:37

C#スクリプトにて、
配列の複数の要素をif文のひとつの条件内で指定することは出来るでしょうか?

配列を
int[] Array = new int[2];

としたとき、 Array[0]とArray[1]がそれぞれ1,0である場合の処理

if (Array[0] == 1 && Array[1] == 0)
{
}

ではスマートでない気がするのですが、
これをひとつの条件にまとめることは可能でしょうか?

イメージ(あくまでイメージ)
if (Array[] == 1,0)
{
}

お二方のご回答により実装できましたので、その一例を記させていただきます。
用語やその使い方が誤っているかもしれませんが、素人の書くこと、どうぞご了承ください。

public class Test : MonoBehaviour
{
//int型のNoという名前(ラベル)とInt型のTimeという名前のタプルを宣言。
(int No, int Time) TEST = (0, 0);

void Start() { //それぞれの要素に適当に値を入れてみる。 TEST.No = 99; TEST.Time = 100; } void update { //if文で二つの値を指定してみる。ここではTEST.Noが99かつ、TEST.Timeが100のとき。 if(TEST == (99, 100)) //Unityのコンソールに値を表示してみる。 Debug.Log(TEST); // (99, 100) と表示される。 Debug.Log(TEST.No + ", " + TEST.Time); //99, 100 と表示される。 }

//このif文は if (TEST.No == 99 && TEST.Time == 100) でも書き表せる。

}

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

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

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

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

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

Zuishin

2020/05/18 07:42

SequentialEqal
Zuishin

2020/05/18 12:17 編集

実際に試してみたところ、StructuralComparisons は使えませんでした。型が違うために配置が違うんだろうと思われます。
退会済みユーザー

退会済みユーザー

2020/05/18 17:44

お手を煩わせてすみません、ありがとうございます。 結構長くなってしまうんですね…
Zuishin

2020/05/18 22:49

何も読んでないのがわかりますね。
退会済みユーザー

退会済みユーザー

2020/05/20 14:16

お返事が遅くなりすみません。 タプルにて実装出来ました。 SequentialEqualは今の私には使い方が判らず、サイトのさらにその先の記事まで拝見させていただきましたが、二つの要素を比較するもののように見え、望みの機能を実装しきれませんでした。 また折を見て読み返し、理解に努めさせて頂こうと思います。ありがとうございました。 それはそれとして、攻撃的なコメントとして通報させていただきました。ご了承ください。
Zuishin

2020/05/20 14:18

実際読んだのは今でしょ。 二つの要素を比較するので、配列にすればいいということなんですが?
guest

回答1

0

ベストアンサー

配列の長さが必ず 2 で固定と予め分かっているのであれば、配列を使わずタプルを使う方が賢明です。

csharp

1var list = new List<(int, int)> 2{ 3 (0, 0), 4 (0, 1), 5 (1, 0), 6 (1, 1), 7}; 8 9foreach (var t in list) 10{ 11 if (t == (1, 0)) 12 { 13 // do something 14 } 15}

どうしても配列でないといけないのであれば Zuishin さんが仰るように SequenceEqual が素直な実装になりそうです。

あるいは、ちょっと Kotlin の Array.componentN を参考にこんなのを用意して

csharp

1public static class ArrayExtensions 2{ 3 public static void Deconstruct<T>(this T[] source, out T item) => 4 item = source[0]; 5 public static void Deconstruct<T>(this T[] source, out T item1, out T item2) => 6 (item1, item2) = (source[0], source[1]); 7 public static void Deconstruct<T>( 8 this T[] source, 9 out T item1, 10 out T item2, 11 out T item3 12 ) => (item1, item2, item3) = (source[0], source[1], source[2]); 13 public static void Deconstruct<T>( 14 this T[] source, 15 out T item1, 16 out T item2, 17 out T item3, 18 out T item4 19 ) => (item1, item2, item3, item4) = (source[0], source[1], source[2], source[3]); 20 public static void Deconstruct<T>( 21 this T[] source, 22 out T item1, 23 out T item2, 24 out T item3, 25 out T item4, 26 out T item5 27 ) => (item1, item2, item3, item4, item5) 28 = (source[0], source[1], source[2], source[3], source[4]); 29}

csharp

1int[] array = new int[2]; 2if (array is (1, 0)) 3{ 4 // do something 5}

とか、ですかね。

投稿2020/05/18 11:45

編集2020/05/18 11:46
htsign

総合スコア870

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

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

退会済みユーザー

退会済みユーザー

2020/05/18 17:55

細かいコードまでありがとうございます。 要素の数は2つで固定なので、明日にでも試してみます。
退会済みユーザー

退会済みユーザー

2020/05/20 14:13

大変助かりました。 最終的に頂戴したコードとは違いますが、タプルにて望み通りの機能を実装できました。 後者については、is演算子(でしょうか?)を使うのは得策ではないという味方をするサイトもあり、また現在の私の実力では手に余るものだと感じますので、いずれもう一度読ませていただきたいと思います。
htsign

2020/05/20 14:26

お力添えできたようでよかったです。 後者について、今回の場合は C# 7から追加された機能 ( https://docs.microsoft.com/ja-jp/dotnet/csharp/deconstruct , および https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/keywords/is#type-pattern ) を使っています。 正直この書き方はかなり hacky で、一般的な C# コードからは離れてしまうためチーム開発でやると多分怒られます???? ただ、使う場面を考えれば Deconstruct と is はかなり有用です。(配列に対して使うのは議論を呼びそうです) > is演算子(でしょうか?)を使うのは得策ではない これはちょっと気になりますね。参考までにその記述のあるサイトをお教えいただいてもよろしいでしょうか?
退会済みユーザー

退会済みユーザー

2020/05/20 14:48 編集

ベストアンサーに選ばせていただきました。はやくその是非も分かるよう努力します。 is演算子についてサイトが判らなくなってしまいました、すみません。 pythonについてはインスタンスIDが影響するようですが https://shobonengine.hatenadiary.org/entry/20120104/1325625895 私が見たC#のサイトでは、is演算子は将来的に消えてしまう可能性がある仕様?といったような書き方がされていたように思いますが、お詳しい方が疑問を呈されるようでしたら、私が他のものと見間違えた可能性の方が高いと思います。 お騒がせいたしました。
Zuishin

2020/05/20 15:04 編集

is 演算子が消えることは絶対にあり得ません。もう少し文字を読みましょう。あまりにも読み方がいい加減です。消えるどころか新バージョンで強化されたばかりです。
退会済みユーザー

退会済みユーザー

2020/05/20 15:08

私の実力、読解力がミジンコ並で書いてあることを全く読み取れないのはまさしくおっしゃる通りで、早く公式リファレンスくらいは満足に読めるようになりたいものだと反省しきりです。 それはそれとして攻撃的なコメントとして通報させていただきました。ご了承ください。
htsign

2020/05/20 15:14

なるほど、確かに Python での is は一意性を見る演算子ですね。 基本的に `if ○○ is not None:` くらいでしか使わないので出番はそこまで多くない気がします。 C# での is は書き方が複数あるのですが、 - `if (value is (1, 0)) { ... }` の場合はほぼ `==` の代わりみたいな使い方に留まる一方で、  `if (value is (int i, 0)) { ... }` とすると「value はタプルであり、2つ目の値が 0 である」ということと「1つ目の値は任意だが int 型であり、その値は i として if ブロック内で使える」という意味になり非常に有用です。 - `if (value is string) { ... }` とすると、「value は string 型である」ことに加えて「value は null ではない」ことが保証されるため、これもまた有用です。 後者の if の使い方は as 演算子とセットで使われることが多かったので、セットで覚えられることがしばしばありました。( "C# is as" とかでググるといろいろ情報が出てきます) 今は `if (value is string s)` で「string 型であること」と「string 型の変数 s を if ブロック内部で使う」が両立するため as 演算子の出番は以前ほどはありません。
Zuishin

2020/05/20 15:17

なんか卑屈な読み方をしてちょくちょく攻撃してますね。落ち着いてください。あなたのことをミジンコと呼んでいるのはあなただけです。
退会済みユーザー

退会済みユーザー

2020/05/20 15:39

htsighn様、補足までいただきありがとうございます。半分も内容を理解できたか怪しいですが、とにかく使い勝手が良いものなんですね…is asについても含めて、今後も読み返し理解を進めさせていただきます。 追記した例文のようなタプルの使い方について、if文の中で二つの要素にそれぞれ別に>や<=等の比較演算子(という言葉が正しいのかも私には判りません、申し訳ありません)を用いることができないか調べている中で、次のサイトを見かけました。 https://ufcpp.net/study/csharp/datatype/tuples/ >new (int x, int y)という書き方は、将来的な言語拡張の予定と被る(被ってしまったら将来の拡張ができない)ため禁止しているようです。 is演算子は、C# 8.0で入った位置パターンとの競合を懸念して、C# 8.0までは認めていませんでした。 こちらの記載や、別途検索にかかってきた三項演算子の是非を問うサイト等をとびとびに見ていく中で、is演算子のことを勘違いしてしまったのかもしれません。大変失礼しました。
htsign

2020/05/20 16:05 編集

あら、 `if (○○ is (1, 0)) { ... }` は C# 8 からでしたか。7 からだと勘違いしていましたね。失礼しました。 ufcpp さんは C# 界隈の有名人が書かれているサイトで大変信憑性の高い情報を提供してくださっている貴重な場所ですね。 > if文の中で二つの要素にそれぞれ別に>や<=等の比較演算子を用いることができないか if では無理のようですが、 switch なら一応可能です。 (なんかもうコメントでやるような内容ではなくなってきたような気もしますが????) ``` var list = new List<(int, int)> {  (1, 0),  (2, 0),  (3, 1),  (4, 2), }; foreach (var t in list) {  switch (t)  {   case (int x, int y) when x % 2 != 0 && y >= 1:    Console.WriteLine(x);    break;  } } ``` これを実行すると 3 のみが出力されます。 case-when で case にヒットするときの条件を絞ることができます。 ここでは x が奇数で y が 1 以上と言っていますから、それに該当するのは 1つだけですよね。 そのときの x を出力、と言っているので 3 が出てくるわけですね。 【追記】なお、`case (int x, int y)` ところは `case var (x, y)` とも書けます。お好きな方で。
Zuishin

2020/05/20 16:08

if ならこうですかね。 if (t is (int x, int y) && x % 2 != 0 && y >= 1) または if (t.Item1 % 2 != 0 && t.Item2 >= 1)
htsign

2020/05/20 16:09

> Zuishin さん お、パターンマッチで得られた変数は if 条件文内でも使えたんですね。 これは知りませんでした。ありがとうございます。
退会済みユーザー

退会済みユーザー

2020/05/20 16:27

if文で利用しようとすると、やはり1つ1つ書かないといけないのですね。ありがとうございます。 switch文で出来ないかは全く考えていませんでした。こちらも実際にやってみて、どちらがより用途に適しているかよく吟味してみます。 何やら少し込み入ったことを伺ってしまったみたいですみません。ありがとうございました。
Zuishin

2020/05/20 22:52

ほんとに読まないなあ。
Zuishin

2020/05/20 23:47 編集

多分やりたいことは array1.Zip(array2, (a, b) => a > b).All(a => a) みたいなことなんでしょうけど。 そして多分配列やタプルではなくクラスを作るべき場面なんでしょうね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問