JavaScript
 Computer >> コンピューター >  >> プログラミング >> JavaScript

JavaScriptで配列内の先行・後続要素が両方存在する値を検索する方法

問題の概要

整数の配列を引数として受け取り、「その要素自身より1小さい値」と「1大きい値」がどちらも同じ配列内に存在する要素だけを抜き出して、新しい配列として返すJavaScript関数を作成してみましょう。

言い換えると、ある要素 num が結果の配列に含まれるのは、num - 1 と num + 1 の両方が元の配列に存在するとき、かつそのときに限られます。

入力例と出力例

たとえば、入力配列が次の通りだったとします。

const arr = [4, 6, 8, 1, 9, 7, 5, 12];

このとき、期待される出力は次のようになります。

const output = [ 6, 8, 7, 5 ];

各要素が採用・除外される理由を整理すると、以下の通りです。

  • 6: 5 と 7 が両方存在 → 採用
  • 8: 7 と 9 が両方存在 → 採用
  • 7: 6 と 8 が両方存在 → 採用
  • 5: 4 と 6 が両方存在 → 採用
  • 4: 3 が存在しない → 除外
  • 9: 10 が存在しない → 除外
  • 1: 0 が存在しない → 除外
  • 12: 11 が存在しない → 除外

コード例

実際のコードは次の通りです。

const arr = [4, 6, 8, 1, 9, 7, 5, 12];

const pickMiddleElements = (arr = []) => {
    const res = [];
    for (let i = 0; i < arr.length; i++) {
        const num = arr[i];
        const hasBefore = arr.includes(num - 1);
        const hasAfter = arr.includes(num + 1);
        if (hasBefore && hasAfter) {
            res.push(num);
        }
    }
    return res;
};

console.log(pickMiddleElements(arr));

実行結果

コンソールには次のように出力されます。

[ 6, 8, 7, 5 ]

コードの解説

この関数では、for ループで配列の各要素を順番に取り出し、Array.prototype.includes() を使って「num - 1」(先行要素)と「num + 1」(後続要素)がそれぞれ配列内に存在するかどうかを判定しています。両方が存在する場合にのみ、その要素を結果配列へ追加しています。

パフォーマンスを上げる改良版:Set を使う

includes() は呼び出すたびに配列全体を走査するため、1回あたりの計算量が O(n) になります。そのため、要素数が多い配列では処理が遅くなる可能性があります。そこで、あらかじめ配列を Set に変換しておくと、存在確認が平均 O(1) となり、全体のパフォーマンスを大幅に改善できます。

const pickMiddleElements = (arr = []) => {
    const set = new Set(arr);
    return arr.filter((num) => set.has(num - 1) && set.has(num + 1));
};

console.log(pickMiddleElements([4, 6, 8, 1, 9, 7, 5, 12])); // [ 6, 8, 7, 5 ]

こちらの書き方はコードも簡潔になり、大きな配列でも高速に動作するため、実務ではこちらのアプローチをおすすめします。

  1. JavaScriptのreduce()メソッドで配列要素の積を求める方法

    問題JavaScriptで、配列 arr を引数として受け取る関数を作成します。この関数は、配列内のすべての要素を掛け合わせた積を計算し、その結果を返す必要があります。解決策:reduce()メソッドを使う配列の全要素を集約して単一の値を得たい場合、Array.prototype.reduce() メソッドが最適です。reduce() は配列の各要素に対してコールバック関数を順に実行し、結果をアキュムレータ(累積値)に蓄えていきます。積を求める場合は、初期値として「1」を指定するのがポイントです。1は乗法における単位元のため、計算結果に影響を与えず、さらに空の配列が渡された場合でも正しく 1

  2. JavaScriptで配列内のすべてのピーク(局所最大値)とその位置を検出する方法

    データ分析や信号処理の現場では、数値の配列の中から「山」にあたる部分、つまり局所最大値(ピーク)とその位置を特定したい場面がよくあります。本記事では、JavaScriptを使って配列内のすべてのピークと、そのインデックス位置を効率的に検出する方法を解説します。 前提となる例 まず、次のようなJavaScriptの配列を用意します。 const arr = [4, 3, 4, 7, 5, 2, 3, 4, 3, 2, 3, 4]; この配列の各要素をY軸の値としてプロットし、隣り合う要素同士をX軸上で等間隔(単位距離)に配置すると、グラフは以下のようになります。 グラフを見ると分かるように、こ