★前回の記事
前回までで8パターンの回転・反転パターンを作成することができましたが、いくつかのピースについては重複があります。例えばこちら↓
このピースの配列は、下記のようになってます。
[ [ [1,1,1], [1,0,1] ], [ [1,1], [1,0], [1,1] ], [ [1,0,1], [1,1,1] ], [ [1,1], [0,1], [1,1] ], [ [1,0,1], [1,1,1] ], [ [1,1], [0,1], [1,1] ], [ [1,1,1], [1,0,1] ], [ [1,1], [1,0], [1,1] ] ]
0番と6番、1番と7番、2番と4番、3番と5番がそれぞれ重複しています。 これからその重複を取り除いていきます。
JavaScriptで配列の重複を取り除くイディオムとして、以下があります。
array.filter((value, i, self) => self.indexOf(value) === i )
Array.filter
(
Array.prototype.filter() - JavaScript | MDN
)
のコールバックに渡した関数は、配列の各値(value)が配列の最初に出てくる時のみtrueとなります。2回目以降の同じ値はコールバックがfalseを返すので、重複が削除された配列を得ることができます。
ただし、今回のように2次元配列の重複を取り除くのに、上記はうまく動作しません。
indexOf
の内部では、===
でオブジェクト同士を比較します。配列の比較の場合、配列の内容が同じでも、違うオブジェクトだと、===
の比較ではfalseとなります。
そこで、代わりにfindIndex
(
Array.prototype.findIndex() - JavaScript | MDN
)を使用します。findIndex
では等しいかどうかを判定するコールバックを渡すことができます。
2次元配列の値同士が等しいかどうか、公式でサポートされている簡単な方法はありません。今回は、JSON.stringify
(
JSON.stringify() - JavaScript | MDN
)
を用いて配列をJSON文字列に変換して比較します。
重複を取り除くuniqSpin
関数は以下のようになります。
function uniqSpin(spinArray) { return spinArray.filter((spin, index, array) => ( index === array.findIndex((spinAnother) => ( JSON.stringify(spin) === JSON.stringify(spinAnother) )) )) }
array.findIndex
の中で、spin
と同じ内容をもつ、一番初めのindexを検索しています。
次にuniqSpin
関数をcreateKataminoSpinList
関数から呼び出します。
function createKataminoSpinList(piece) { let spinArray = [] spinArray[0] = copyArrayOfArray(piece) spinArray[7] = transpose(spinArray[0]) spinArray[1] = copyArrayOfArray(spinArray[7]).reverse() spinArray[6] = transpose(spinArray[1]) spinArray[2] = copyArrayOfArray(spinArray[6]).reverse() spinArray[5] = transpose(spinArray[2]) spinArray[3] = copyArrayOfArray(spinArray[5]).reverse() spinArray[4] = transpose(spinArray[3]) // スピンの重複を取り除く const uniqSpinArr = uniqSpin(spinArray) console.log("uniqSpinArr", uniqSpinArr) return uniqSpinArr }
実行してみて、下記のようになって入れば成功です。
以上で2次元配列の重複を取り除くことができました。ここまでで配列の内容は以下のようになっています。
★次回の記事
★目次