LoginSignup
1
0

More than 3 years have passed since last update.

すごく無理やり「同じ要素が連続する」配列の判定

Last updated at Posted at 2021-01-17

「同じ要素が連続である」配列の判定を行いたくていろいろ試行錯誤したので、ここにメモ。

sample.js
let array = [12, 2, 0, 0, 0, 5];

↑の配列のような場合だと、「0が3回連続である」配列だからtrueを返す、というような処理を書きたい

試したこと①:filterメソッドでできるかいったん確認

sample.js
let target_array = [0, 0, 0]; 
let array = [12, 2, 0, 0, 0, 5];

const result = array.filter(item => item === target_array);
console.log(result);

// 実行結果
// []

「0が3回連続で続く配列」と同じ要素を取り出そうとしてfilterメソッドで試したが、配列の要素に配列を当てはめようとしているのでもちろんできない。

試したこと②:配列の重複を利用

2つの配列を比較して重複を取り出すことにしようってなった。

(参考記事)
https://www.dkrk-blog.net/javascript/duplicate_an_array

sample.js
let target_array = [0, 0, 0]; 
let array = [12, 2, 0, 0, 0, 5];

const result = array.filter(item => target_array.includes(item)).length === 3
console.log(result);

// 実行結果
// true

target_arrayの中のarrayと一致する要素を取得、その個数が3つあるならtrueを返す。

「これでtrueになった!!」って思っていたけど、いろいろ配列を変えてみると思い通りの判定にならず。。。。

これは「target_arrayの要素の中でarrayの要素と一致するものは3個かどうか」っていう処理だから、目的の処理ではないって現実を突きつけられる。。。

そもそも、配列の重複で確認できるは「配列の要素」だけで、「配列の順番」は同時に確認できないだろって自分でツッコミしてました。

ポイントにした点

配列の重複を確認しているときに、「配列に同じ要素が並んでいる」という考え方ではなく「配列の要素が連続して同じ」っていう視点に切り替えることにした。

端的に言えば、「配列の同じ要素のインデックス番号に取得してそれが連続しているかどうか」っていう処理を書こうってなった。

強引にインデックス番号を取得:findIndex

対象の要素のインデックス番号を取得するのは、findIndexメソッドだからそれを使用することにした。

ここで問題になってくるのが、findIndexメソッドは最初のインデックス番号しか取得できないってことだが、これについては強引に突破することにした。

sample.js
let array = [12, 2, 0, 0, 0, 5];

let first_zero = parent.findIndex(element => element === 0);
if (first_zero !== -1) {
    delete array[first_zero];
}
console.log(array);

let second_zero = parent.findIndex(element => element === 0);
if (second_zero !== -1) {
    delete array[second_zero];
}
console.log(array);

let third_zero = parent.findIndex(element => element === 0);
if (first_zero !== -1 && second_zero !== -1) {
    array[first_zero] = 0;
    array[second_zero] = 0;
}
console.log(array);

console.log(first_zero);
console.log(second_zero);
console.log(third_zero);

let first_condition = first_zero + 1 === second_zero
let second_condition = second_zero + 1 === third_zero

if (first_condition && second_condition) {
 console.log('成功');
} else {
 console.log('失敗');
}

// 実行結果
// [12, 2, , 0, 0, 5]
// [12, 2, 0, , 0, 5]
// [12, 2, 0, 0, 0, 5]
// 2
// 3
// 4
// 成功

「最初のインデックス番号しか取れないなら、取得する度に要素を空にしよう」という考えでdelete演算子を使用。

空のまま放置はさすがにまずいから、third_zeroを取得したタイミングで0を戻す処理も一緒に添える。

ここで取得してきたインデックス番号が連番していたら、「成功」が呼び出される仕組み。

まとめ

これで一応目的の処理が問題なくできたけど、綺麗なコードではないから別の通りを考えないといけないなと思いつつある程度に煮詰まったからここにアウトプットしました。

もっと最適な処理がある場合は、コメントで教えていただけると幸いです。

最後まで読んでくれてありがとうございました。

1
0
6

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0