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

JavaScriptで配列から一意の要素(重複なし)だけを抽出する方法

配列の中に同じ値が複数回登場する場合、「一度だけしか出現しない要素」だけを取り出したいケースはよくあります。この記事では、そのような処理をJavaScriptの関数として実装する方法を解説します。

やりたいこと

リテラルの配列を受け取り、その中で重複していない要素のみを含む新しい配列を返す関数を作成します。

たとえば、次のような配列が与えられたとします。

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

この配列では 7198 が複数回出現しています。一方、56 は一度しか登場しません。したがって、期待される出力は次のようになります。

const output = [5, 6];

実装方法:indexOf と lastIndexOf を活用

要素が「一度しか出現しない」かどうかを判定するには、indexOf()(先頭からの位置)と lastIndexOf()(末尾からの位置)の結果を比較するのがシンプルです。両者が一致すれば、その要素は配列内にひとつしか存在しないことになります。

以下がサンプルコードです。

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

const findDistinct = arr => {
    const res = [];
    for (let i = 0; i < arr.length; i++) {
        // 先頭と末尾の出現位置が異なる = 重複している要素なのでスキップ
        if (arr.indexOf(arr[i]) !== arr.lastIndexOf(arr[i])) {
            continue;
        }
        res.push(arr[i]);
    }
    return res;
};

console.log(findDistinct(arr));

実行結果

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

[5, 6]

コードのポイント

  • indexOf(arr[i]) は配列の先頭から検索した際の最初のインデックスを返します。
  • lastIndexOf(arr[i]) は末尾から検索した際の最後のインデックスを返します。
  • 両者の値が一致していれば、その要素は配列内に1つしか存在しないため、結果配列に追加します。
  • 一致しない場合は重複しているため、continue でスキップします。

補足:より効率的にしたい場合

上記の方法は直感的で分かりやすい一方、indexOflastIndexOf を毎回呼び出すため、計算量は O(n²) になります。大きな配列を扱う場合は、Map やオブジェクトを使って各要素の出現回数を先にカウントしておく方法(計算量 O(n))がおすすめです。

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

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

  2. JavaScriptで複数の文字列に共通する文字を重複込みで抽出する方法

    問題文字列の配列 arr を第一引数(かつ唯一の引数)として受け取るJavaScript関数を作成することを考えます。この関数の役割は、配列内のすべての文字列に出現する文字を抽出し、それらを配列として返すことです。重複も含めて扱う必要がある点に注意してください。たとえば、ある文字がすべての文字列の中で2回ずつ出現している場合(3回ではない場合)、最終的な結果にもその文字を2回だけ含めます。入力と出力の例たとえば、関数への入力が次のような場合を考えてみましょう。const arr = [door, floor, crook];r は3つの文字列すべてに1回ずつ現れ、o は door に2回、fl