配列から重複を削除する

概要:このチュートリアルでは、JavaScriptで配列から重複を削除する方法を学習します。

1) Set を使用して配列から重複を削除する

Set は、一意の値のコレクションです。重複を含む配列から重複を削除するには

  • まず、重複を含む配列をSetに変換します。新しいSetは暗黙的に重複要素を削除します。
  • 次に、Setを配列に戻します。

次の例では、Setを使用して配列から重複を削除します。

let chars = ['A', 'B', 'A', 'C', 'B'];
let uniqueChars = [...new Set(chars)];

console.log(uniqueChars);Code language: JavaScript (javascript)

出力

[ 'A', 'B', 'C' ]Code language: JSON / JSON with Comments (json)

2) indexOf()メソッドとfilter()メソッドを使用して配列から重複を削除する

indexOf()メソッドは、配列内で要素の最初の出現インデックスを返します。例えば

let chars = ['A', 'B', 'A', 'C', 'B'];
chars.indexOf('B');Code language: JavaScript (javascript)

出力

1  

重複アイテムは、そのインデックスがindexOf()値と異なるアイテムです。

let chars = ['A', 'B', 'A', 'C', 'B'];

chars.forEach((c, index) => {
    console.log(`${c} - ${index} - ${chars.indexOf(c)}`);
});
Code language: JavaScript (javascript)

出力

A - 0 - 0
B - 1 - 1
A - 2 - 0
C - 3 - 3
B - 4 - 1

重複を削除するには、filter()メソッドを使用して、インデックスがそのindexOf値と一致する要素のみを含めます。

let chars = ['A', 'B', 'A', 'C', 'B'];

let uniqueChars = chars.filter((c, index) => {
    return chars.indexOf(c) === index;
});

console.log(uniqueChars);
Code language: JavaScript (javascript)

出力

[ 'A', 'B', 'C' ]
Code language: JSON / JSON with Comments (json)

重複値を見つけるには、条件を反転する必要があります。

let chars = ['A', 'B', 'A', 'C', 'B'];

let dupChars = chars.filter((c, index) => {
    return chars.indexOf(c) !== index;
});

console.log(dupChars);Code language: JavaScript (javascript)

出力

[ 'A', 'B' ]Code language: JSON / JSON with Comments (json)

3) forEach()メソッドとinclude()メソッドを使用して配列から重複を削除する

include()は、要素が配列にある場合はtrue、そうでない場合はfalseを返します。

次の例では、配列の要素を反復処理し、まだ存在しない要素のみを新しい配列に追加します。

let chars = ['A', 'B', 'A', 'C', 'B'];

let uniqueChars = [];
chars.forEach((c) => {
    if (!uniqueChars.includes(c)) {
        uniqueChars.push(c);
    }
});

console.log(uniqueChars);Code language: JavaScript (javascript)

出力

[ 'A', 'B', 'C' ]    Code language: JSON / JSON with Comments (json)

4) 1つのプロパティでオブジェクトの配列から重複を削除する

次のオブジェクトの配列があるとします。

const members = [
  { id: 1, name: 'John' },
  { id: 2, name: 'Jane' },
  { id: 1, name: 'Johnny' },
  { id: 4, name: 'Alice' },
];Code language: JavaScript (javascript)

最初の要素のidは、3番目の要素と同じです。people配列から重複を削除するには、次のようにします。

const unique = [...new Map(members.map((m) => [m.id, m])).values()];
console.log(unique);Code language: JavaScript (javascript)

出力

[
  { id: 1, name: 'Johnny' },
  { id: 2, name: 'Jane' },
  { id: 4, name: 'Alice' }
]Code language: JavaScript (javascript)

動作方法。

まず、map()メソッドを使用して、元の配列から新しい配列を作成します。

members.map((m) => [m.id, m])Code language: JavaScript (javascript)

配列の配列を返します。各ネストされた配列には、idの値と対応するオブジェクトが含まれています。

[
  [ 1, { id: 1, name: 'John' } ],
  [ 2, { id: 2, name: 'Jane' } ],
  [ 1, { id: 1, name: 'Johnny' } ],
  [ 4, { id: 4, name: 'Alice' } ]
]Code language: JavaScript (javascript)

次に、新しいMap()オブジェクトを作成して重複を削除します。

const newMap = new Map(newArray);
console.log(newMap);Code language: JavaScript (javascript)

出力

Map(3) {
  1 => { id: 1, name: 'Johnny' },
  2 => { id: 2, name: 'Jane' },
  4 => { id: 4, name: 'Alice' }
}Code language: PHP (php)

Mapオブジェクトのキーは一意であるため、配列の配列からMapを作成することで、キー(この場合はid)で重複オブジェクトが削除されます。

次に、values()メソッドを呼び出すことで、Mapのエントリのイテレータを取得します。

const iterator = newMap.values();
console.log(iterator);Code language: JavaScript (javascript)

出力

[Map Iterator] {
  { id: 1, name: 'Johnny' },
  { id: 2, name: 'Jane' },
  { id: 4, name: 'Alice' }
}Code language: JavaScript (javascript)

最後に、スプレッド演算子を使用してイテレータを配列に変換します。

const uniqueMembers = [...iterator];
console.log(uniqueMembers);Code language: JavaScript (javascript)

出力

[
  { id: 1, name: 'Johnny' },
  { id: 2, name: 'Jane' },
  { id: 4, name: 'Alice' }
]Code language: JavaScript (javascript)

すべてをまとめる

const members = [
  { id: 1, name: 'John' },
  { id: 2, name: 'Jane' },
  { id: 1, name: 'Johnny' },
  { id: 4, name: 'Alice' },
];

const newArray = members.map((m) => [m.id, m]);
const newMap = new Map(newArray);
const iterator = newMap.values();
const unique = [...iterator];

console.log(unique);Code language: JavaScript (javascript)

次の4行のコード

const newArray = members.map((m) => [m.id, m]);
const newMap = new Map(newArray);
const iterator = newMap.values();
const unique = [...iterator];Code language: JavaScript (javascript)

…は1行に短縮できます

const unique = [...new Map(members.map((m) => [m.id, m])).values()];Code language: JavaScript (javascript)

したがって

const members = [
  { id: 1, name: 'John' },
  { id: 2, name: 'Jane' },
  { id: 1, name: 'Johnny' },
  { id: 4, name: 'Alice' },
];

const unique = [...new Map(members.map((m) => [m.id, m])).values()];

console.log(unique);Code language: JavaScript (javascript)

次のunique()関数は、オブジェクトの配列を受け取り、プロパティによって一意の要素を返します。

const uniqueBy = (arr, prop) => {
  return [...new Map(arr.map((m) => [m[prop], m])).values()];
};Code language: JavaScript (javascript)

例えば、uniqueBy()関数を用いて、members配列から重複要素を次のように削除できます。

const members = [
  { id: 1, name: 'John' },
  { id: 2, name: 'Jane' },
  { id: 1, name: 'Johnny' },
  { id: 4, name: 'Alice' },
];

const uniqueBy = (arr, prop) => {
  return [...new Map(arr.map((m) => [m[prop], m])).values()];
};

console.log(uniqueBy(members, 'id'));Code language: JavaScript (javascript)

5) 複数のプロパティでオブジェクトの配列から重複を削除する

次のunique()関数は、オブジェクトの配列から重複を削除します。重複のロジックは、コールバック関数によって指定されます。


function unique(a, fn) {
  if (a.length === 0 || a.length === 1) {
    return a;
  }
  if (!fn) {
    return a;
  }

  for (let i = 0; i < a.length; i++) {
    for (let j = i + 1; j < a.length; j++) {
      if (fn(a[i], a[j])) {
        a.splice(i, 1);
      }
    }
  }
  return a;
}Code language: JavaScript (javascript)

動作方法。

まず、要素が0個または1個の場合は、同じ配列を返します。

if (a.length === 0 || a.length === 1) {
  return a;
}Code language: JavaScript (javascript)

次に、コールバックが渡されていない場合は、入力配列を返します。

if (!fn) {
  return a;
}Code language: JavaScript (javascript)

次に、入力配列の要素を2回反復処理し、最初の要素と他の要素を連続して比較します。2つの要素がコールバック関数(fn)をtrueにする場合、splice()メソッドを使用して、その要素を配列から削除します。

for (let i = 0; i < a.length; i++) {
  for (let j = i + 1; j < a.length; j++) {
    if (fn(a[i], a[j])) {
      a.splice(i, 1);
    }
  }
}Code language: JavaScript (javascript)

次の例では、unique()関数を使用して、idnameの両方のプロパティでmembers配列から重複を削除します。

function unique(a, fn) {
  if (a.length === 0 || a.length === 1) {
    return a;
  }
  if (!fn) {
    return a;
  }

  for (let i = 0; i < a.length; i++) {
    for (let j = i + 1; j < a.length; j++) {
      if (fn(a[i], a[j])) {
        a.splice(i, 1);
      }
    }
  }
  return a;
}

const members = [
  { id: 1, name: 'John' },
  { id: 2, name: 'Jane' },
  { id: 1, name: 'John' },
  { id: 4, name: 'Joe' },
];

const uniqueMembers = unique(
  members,
  (a, b) => (a.id === b.id) & (a.name === b.name)
);

console.log(uniqueMembers);
Code language: JavaScript (javascript)

出力

[
  { id: 2, name: 'Jane' },
  { id: 1, name: 'John' },
  { id: 4, name: 'Joe' }
]Code language: JavaScript (javascript)

このチュートリアルでは、JavaScriptで配列から重複を削除するいくつかのテクニックを学習しました。

このチュートリアルは役に立ちましたか?