5つの文字列を入れた配列があり、その並び順ごとに処理を分岐させたいのですがうまくいきません。
おそらく基本的な何かを理解していないのだと思いますが、ご教授いただけますと幸いです。
javascript
1switch( Array ) { 2 case ["F","F","T","T","T"]: 3 console.log('Aの処理'); 4 break; 5 6 7 case ["F","T","T","T","T"]: 8 console.log('Bの処理'); 9 break; 10 11 }
上記でやりたいことが伝わるでしょうか。
FFFFFならAの処理、
TFFFFならBの処理、
TTFFFならCの処理…と、すべての組み合わせで処理を変えたいのです。
Arrayに5つの文字列を入れるところまではできているのですが…。
よろしくお願いいたします。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答5件
0
ベストアンサー
こんにちは。
おそらく基本的な何かを理解していないのだと思いますが、
とおっしゃっている、"基本的な何か" とは以下の2点かと思われます。
(1) javascript の switch文で、 switch(x ) で与える x と各 case y : の y とは同値演算子 ===
で比較されること。(つまり x === y が true になる case y : が選ばれる。)
(2) 二つのArrayオブジェクト a
と b
があり、両者が過不足なく同じ要素を同じ順番で含んでいても、a
と b
が別個のオブジェクトであれば、 a === b
は false になること
上記の(1) については、以下に記載があります。
ECMAScript® Language Specification: 12.11 The switch Statement
If input is equal to clauseSelector as defined by the === operator, then …
(2) については、以下のようにして確かめられます。
shell
1$ node -v 2v10.8.0 3$ node 4> var a = ["T","F","T","F","T"] 5undefined 6> var b = ["T","F","T","F","T"] 7undefined 8> a === b 9false 10>
2つの配列a
と b
が、同じ要素を同じ順番で過不足なく持っている、すなわち「a
とb
は内容が同じ配列
である」という判定を、どのようなコードで書けばよいか? という問題は、以下の投稿
- stackoverflow: How to compare arrays in JavaScript?
からも分かるように、様々な案が出てくるテーマでもあります。
ですが、上記のstackoverflowの質問への回答で、一番得票数が多い Array.prototype.equalsを自作するという案だと、MikiSFさんのご質問にあるswitch 〜 case
を使うことができません。
MikiSFさんのご質問の解法として、あくまでswitch 〜 case
を使うことにするならば、対象とする配列の要素を結合した文字列をswitchの対象にするのが分かり易い方法かなと思います。つまり、["F","F","T","T","T"]
であれば、"FFTTT"
をswitchの対象とします。以下はコード例です。
javascript
1const sampleAry = ["F","F","T","T","T"]; 2 3switch (sampleAry.join('')) { 4 case 'FFTTT': 5 console.log('Aの処理'); 6 break; 7 case 'FTTTT': 8 console.log('Bの処理'); 9 break; 10 default: 11 console.log('その他の処理'); 12 break; 13}
上記を実行すると、Aの処理
と表示されます。
以上参考になれば幸いです。
追記
配列要素の "T" を"1"、"F"を"0"と置き換え、要素を結合した文字列を作ると、例えば["T","F","T","F","T"] は "10101" となり、さらに"10101" を2進数と考えれば、 10進数としては 21 です。このように "T"か "F" を持つ配列を対応する10進数に変換した値で switch させる手もあるかと思いました。
具体的なコードとしては、少しトリッキーかもしれませんが、例えば以下のように、Array.prototype.valueOf
メソッドをオーバーライドし対応する10進数を返すようにしておくと、配列の変数sampleAry
があったときに、+
を変数の前に置いて +sampleAry
とするとvalueOf
が呼ばれて10進数に変換されます。
javascript
1Array.prototype.valueOf = function() { 2 return parseInt(this.map(e => e === 'T' ? '1':'0').join(''), 2); 3}; 4 5const sampleAry = ["T","F","T","F","T"]; // 2進数の10101を表すものと考えれば、10進数だと21 6 7switch(+sampleAry) { 8 case 0: 9 console.log('["F","F","F","F","F"] の場合の処理'); 10 break; 11 case 1: 12 console.log('["F","F","F","F","T"] の場合の処理'); 13 break; 14 case 2: 15 console.log('["F","F","F","T","F"] の場合の処理'); 16 break; 17 // ・・・ 18 case 21: 19 console.log('["T","F","T","F","T"] の場合の処理'); 20 break; 21 // ・・・ 22 case 31: 23 console.log('["T","T","T","T","T"] の場合の処理'); 24 break; 25 default: 26 break; 27}
上記を実行すると、case 21:
に該当して、["T","F","T","F","T"] の場合の処理
と表示されます。(同じコードを、https://jsfiddle.net/jun68ykt/kose0cqu/19/ にも上げておきました。)
以下、蛇足です。
質問者のMikiSFさんから
switchにこだわる理由があるわけではないので、他の方法も調べてみます!
とのコメントを頂きましたので、以下を補足します。
2つの配列が同じ内容である判定関数を自作せずに、配列などの操作でよく使われるライブラリ Lodash を利用する手もあります。これの _.isEqual(value, other)を使ったコードを以下に上げておきました。
https://jsfiddle.net/jun68ykt/jqp63Lum/6/
ご参考まで。
何度もお節介すみません。
switch 〜 case
を使うにせよ、if 〜 else if
を使うにせよ、該当する処理にたどりつくのに、caseあるいはifの数に比例した時間がかかります。(計算量のオーダーが O(n) である、と言ったります。 ) 言い換えると、FFFFF
からTTTTT
まですべてのケースは2の5乗で32個あり、これらのそれぞれに case または if があるとすると、最悪の場合は32回の比較をへて、ようやく該当する処理が決まるということがあり得ます。
これを避けたいので、私がもし業務上で、このご質問と同様の課題に遭遇したら、おそらく以下のコードをベースにするでしょう。
javascript
1const operations = { 2 FFFFF() { console.log('[F,F,F,F,F]の処理'); }, 3 FFFFT() { console.log('[F,F,F,F,T]の処理'); }, 4 /* ・・・ */ 5 TFTFT() { console.log('[T,F,T,F,T]の処理'); }, 6 /* ・・・ */ 7 TTTTT() { console.log('[T,T,T,T,T]の処理'); }, 8}; 9 10const sampleAry = ["T","F","T","F","T"]; 11 12operations[sampleAry.join('')](); // => "[T,F,T,F,T]の処理" と出力される。
※ https://jsfiddle.net/jun68ykt/1bLm7eyd/14/ にも上げておきました。
これに、エラー処理などを加えたり適宜リファクタして、安全かつ最適化されたコードに仕上げていくだろうと思います。
投稿2018/08/18 14:39
編集2018/08/20 01:09総合スコア9058
0
2つの配列を受け取ってその内容が一致しているかを判定する関数があれば、「5つの文字列を入れた配列の並び順」ごとに処理を分岐させることができます。
それさえ出来れば、あとは各パターンごとに処理を書いていくだけです。
「2つの配列を受け取ってその内容が一致しているかを判定する関数」は自前で作ってしまいましょう。
javascript
1var hoge = ["F","F","T","T","T"]; // 5つの文字列を入れた配列 2 3// 各パターンごとに処理 4if (isEqualArray(hoge, ["F","F","T","T","T"])) { 5 console.log('Aの処理'); 6} else if (isEqualArray(hoge, ["F","T","T","T","T"])) { 7 console.log('Bの処理'); 8} else { 9 console.log('AでもBでもない処理'); 10} 11 12// 2つの配列を受け取ってその内容が一致しているかを判定する関数 13function isEqualArray(array1, array2) { 14 if (array1.length != array2.length) { return false; } 15 16 for (var i=0; i<array1.length; i++) { 17 if (array1[i] != array2[i]) { return false; } 18 } 19 20 return true; 21}
投稿2018/08/18 14:19
編集2018/08/18 14:21総合スコア4524
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
Reference型
オブジェクトはReference型なので、
JavaScript
1console.log(["F","F","T","T","T"] === ["F","F","T","T","T"]); // false
JSON.stringify()
配列の要素値がPrimitive型なら、
JavaScript
1'use strcit'; 2function sample (array) { 3 switch (JSON.stringify(array)) { 4 case '["F","F","T","T","T"]': 5 console.log('処理A'); 6 break; 7 case '["F","T","T","T","T"]': 8 console.log('処理B'); 9 break; 10 } 11} 12 13sample(["F","F","T","T","T"]); 14sample(["F","T","T","T","T"]);
フラグ管理
Re: MikiSF さん
投稿2018/08/19 01:56
編集2018/08/19 06:07総合スコア18162
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/08/19 05:36
2018/08/19 07:10
2018/08/19 07:58 編集
2018/08/19 09:24
2018/08/19 10:04 編集
2018/08/20 02:08
2018/08/20 03:29
2018/08/25 14:52 編集
2018/08/21 03:29
2018/08/25 14:52 編集
2018/08/24 12:11
2018/08/24 12:14