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

JavaScriptで配列内の順序が乱れた要素を検索・抽出する方法

数値の配列が昇順に並んでいるはずなのに、一部の要素だけが本来の順序から外れてしまっている――そんなケースを想定してみましょう。

本記事では、そのような配列を受け取り、順序が乱れている要素だけを集めた部分配列を返すJavaScript関数の実装方法をわかりやすく解説します。

実装の考え方

Array.prototype.filter()メソッドを使い、各要素を「次に期待される値」と比較することで、順序から外れた要素だけを抽出できます。filter()の第2引数(thisArg)にオブジェクトを渡すことで、コールバック関数内で比較用の状態を保持できるのがポイントです。

サンプルコード

コードは次のとおりです。

const arr = ["2", "3", "7", "4", "5", "6", "1"];
const findOutOfOrder = arr => {
   let notInOrder = [];
   notInOrder = arr.filter((el, ind) => {
      return ind && this.next !== +el || (this.next = +el + 1, false);
   }, {
      next: null
   });
   return notInOrder;
};
console.log(findOutOfOrder(arr));

出力結果

コンソールには以下のように表示されます。

[ '7', '1' ]

コードの仕組み

このコードの動作を順を追って見ていきましょう。

  • filter()の第2引数として{ next: null }というオブジェクトを渡すことで、コールバック内のthis.nextに「次に期待される数値」を保持できます。
  • +elにより、文字列の配列要素を数値へ変換して比較しています。
  • 先頭の要素(インデックス0)には比較対象がないため、条件のind &&によって必ずスキップされます。
  • 要素が期待値と一致すれば、期待値を+1して更新し、falseを返すので結果には含まれません。
  • 期待値と一致しなければtrueを返し、その要素は「順序が乱れた要素」として結果の配列に追加されます。このとき期待値は更新されない点に注意してください。

実行例での判定の流れ

配列["2", "3", "7", "4", "5", "6", "1"]の場合、「2」「3」までは連続した並びとして処理され、次に期待される値は「4」になります。しかしインデックス2の実際の要素は「7」なので、「7」は順序が乱れた要素として記録されます。その後は「4」「5」「6」が期待値どおりに並んでいますが、末尾の「1」が期待値「7」と一致しないため、最終的な出力は['7', '1']となるのです。

なお、この実装は「最初の要素から始まる連続する数値列」を基準に順序を判定している点にも留意してください。基準となる並び方が異なる場合は、比較ロジックを適宜調整するとよいでしょう。


  1. 【JavaScript】_.where()メソッドで特定の条件に一致するすべての要素を取得する方法

    JavaScriptには数多くのフレームワークやユーティリティライブラリが存在しますが、その中でもunderscore.jsは軽量かつ高機能なライブラリとして広く使われています。underscore.jsが提供する便利な関数のひとつが_.where()で、これを使うと配列の中から特定の条件に一致する要素を簡単に見つけ出すことができます。 _.where()は、指定された条件を配列内の各要素が満たしているかどうかを順番に判定し、条件を満たした要素だけを新しい配列として返すメソッドです。たとえば「配列の中から給与が15000と等しい人をすべて探したい」という場合、_.where()は全要素を精査し

  2. 複数の値でJavaScript配列の要素を検索する方法

    JavaScriptである配列(arr)が、別の配列(arr1)の複数の値・すべての要素を含んでいるかどうかを確認したい場面はよくあります。そんなときは、every()メソッドとincludes()メソッドを組み合わせることで、シンプルに判定できます。以下はそのサンプルコードです。 コード例 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content=