javascript 配列から重複したデータを抽出する

javascript 配列から重複したデータを抽出する

javascriptで、filterメソッドを使用して配列から重複したデータを抽出するサンプルコードを記述してます。

環境

  • OS windows10 pro 64bit
  • Apache 2.4.43
  • ブラウザ chrome 103.0.5060.114

filterメソッド使い方

filterメソッドを使うと、配列から指定した条件で値を抽出することが可能です。

配列.filter ( コールバック関数 )

filterメソッドを使って、配列から重複を取り除くには、
条件に
要素の番号と最後に見つかった位置が異なる場合(重複確認)
かつ
最初に見つかった位置と、配列の要素番号が一緒の場合(重複した最初のデータ)
のみとすれば可能です。

let arr2 = arr1.filter(function (val, idx, arr) {

  // 要素の番号と最後に見つかった位置が異なる場合
  // かつ
  // 最初に見つかった位置と、配列の要素番号が一緒の場合 
    console.log(
    "配列の値 : " + val + 
    " 最初に見つかった位置 : " + arr.indexOf(val) + 
    " 最後に見つかった位置 : " + arr.lastIndexOf(val)+ 
    " 要素番号 : " + idx
  )

  return   arr.lastIndexOf(val) !== idx && arr.indexOf(val) === idx ;

});

以下は、配列 [ 7, 6, 3, 1, 6]に、上記のfilterメソッドを使用した結果です。

const arr1 =  [ 7, 6, 3, 1, 6]

let arr2 = arr1.filter(function (val, idx, arr) {

  console.log(
    "配列の値 : " + val + 
    " 最初に見つかった位置 : " + arr.indexOf(val) + 
    " 最後に見つかった位置 : " + arr.lastIndexOf(val)+ 
    " 要素番号 : " + idx
  )

  return arr.lastIndexOf(val) !== idx && arr.indexOf(val) === idx

});

console.log(arr2)

実行結果をみると、重複しているデータである「6」が抽出されていることが確認できます。

また、アロー関数を使用すると1行で記述することも可能です。
※引数に指定してする値は、使用できる変数名であればなんでも問題ないです。

let arr = [1, 2, 2, 3, 5, 5];

arr = arr.filter( (x,i,s) => s.indexOf(x) !== s.lastIndexOf(x) );

console.log(arr);
// [2, 2, 5, 5]

重複してる値をユニークで抽出したい場合は、以下のように条件を追加します。

let arr = [1, 2, 2, 3, 5, 5];

arr = arr.filter( (x,i,s) => s.lastIndexOf(x) !== i && s.indexOf(x) === i );

console.log(arr);
// [2, 5]

重複を除く

逆に「filter」を使用して、重複を除く場合は、以下となります。

let arr = [1, 2, 2, 3];

arr = arr.filter( (x,i,s) => s.indexOf(x) === i );

console.log(arr);
// [1, 2, 3]

サンプルコード

以下は、「抽出」ボタンをクリックすると、ランダムな配列を作成して、重複しているデータを表示するサンプルコードとなります。

※cssには「bootstrap material」を使用してます。

<!DOCTYPE html>
<html lang="ja">

<head>
  <meta charset="utf-8">
  <title>mebeeサンプル</title>
  <!-- MDB -->
  <link href="https://cdnjs.cloudflare.com/ajax/libs/mdb-ui-kit/4.2.0/mdb.min.css" rel="stylesheet" />
</head>

<body>

  <div class="container text-center w-50" style="margin-top:200px">

    <h2><span class="badge badge-info">生成した配列</span></h2>
    <ul id="txt" class="list-group list-group-light"></ul>

    <h2><span class="badge badge-info">重複データ</span></h2>
    <ul id="txt2" class="list-group list-group-light"></ul>

    <button type="button" class="btn btn-info" onclick="hoge();">抽出</button>

  </div>

  <script>

    function hoge() {

      //ランダムな9までの5個の配列を生成
      let arr1 = radarr(5);

      // 乱数を表示
      disp(arr1, "txt");

      let arr2 = arr1.filter(function (val, idx, arr) {
        // 要素の番号と最後に見つかった位置が異なる場合
        // かつ
        // 最初に見つかった位置と、配列の要素番号が一緒の場合 
        console.log("配列の値 : " + val + " 最初に見つかった位置 : " + arr.indexOf(val) + " 最後に見つかった位置 : " + arr.lastIndexOf(val) + " 要素番号 : " + idx);
        return arr.lastIndexOf(val) !== idx && arr.indexOf(val) === idx;

      });

      // 配列を表示
      disp(arr2, "txt2");

    }

    function radarr(len) {

      //ランダムな9までの配列を生成
      let arr = [];
      let num = 10;
      let length = len;
      for (let i = 0; i < length; i++) {
        arr.push(Math.floor(Math.random() * num));
      }

      return arr;

    }

    //フロントに表示する関数
    function disp(arr, id) {
      let text = [];
      for (let i = 0; i < arr.length; i++) {
        text.push('<li class="list-group-item">' + arr[i] + '</li>');
      }
      //innerHTMLを使用して表示    
      document.getElementById(id).innerHTML = text.join('');
    }

  </script>
</body>

</html>

重複したデータが抽出されていることが確認できます。