---
type: how-to
language: javascript
slug: array/compare
title: "2つの配列を比べる — 同じか、共通は何か"
title_tag: "JavaScript 配列を比較する — === が使えない理由と代替"
summary: >
  配列同士を === で比べても中身は見ません。中身が同じか調べる方法、順序を無視して比べる方法、
  共通・差分の求め方、オブジェクトの配列で気をつけることまで実行して確かめます。
description: >
  配列の === は「同じ実体か」しか見ません。中身で比べる書き方、順序を無視する比べ方、
  Set の演算による共通と差分、JSON での比較が鍵の順に左右される点まで示します。
status: published
difficulty: 2
minutes: 8

versions:
  verified: "Node 22.22.3"
  since: "ES2015"
  deprecated: null
  removed: null

sources:
  - title: "IsStrictlyEqual — ECMAScript® 2026 Language Specification"
    url: "https://tc39.es/ecma262/#sec-isstrictlyequal"
  - title: "Set Objects — ECMAScript® 2026 Language Specification"
    url: "https://tc39.es/ecma262/#sec-set-objects"
  - title: "Array.prototype.every — MDN"
    url: "https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/every"

terms: [参照, 集合演算, 浅い比較]

links:
  related:
    - javascript/reference/collection/map-set
    - javascript/how-to/array/remove-duplicates
    - javascript/why/strict-equality

content_updated_at: 2026-09-08
published_at: 2026-09-08
---

## 答え

**`===` は使えません。** 中身ではなく「[key:同じ実体か]」を見るからです。

```js run
const a = [1, 2, 3];
const b = [1, 2, 3];

console.log(a === b);
```
```output
false
```

中身で比べるなら、長さと要素を順に見ます。

```js run
function sameArray(a, b) {
  return a.length === b.length && a.every((value, i) => value === b[i]);
}

console.log(sameArray([1, 2, 3], [1, 2, 3]));
console.log(sameArray([1, 2], [1, 2, 3]));
console.log(sameArray([1, 2, 3], [3, 2, 1]));
```
```output
true
false
false
```

**長さを先に見る**のが要点です。見ないと、短いほうを長いほうと比べたときに通ってしまいます。

## 順序を無視して比べる

「同じものが揃っているか」だけを見たいなら、並べ替えてから比べます。

```js run
const a = [3, 1, 2];
const b = [1, 2, 3];

console.log(JSON.stringify(a) === JSON.stringify(b));
console.log(JSON.stringify([...a].sort()) === JSON.stringify([...b].sort()));
```
```output
false
true
```

`[...a]` で複製してから並べ替えています。
[bad:`a.sort()` と書くと元の配列が変わります。]
→ [sort() と toSorted()](/ja/javascript/reference/array/sort/)

重複を気にしないなら `Set` のほうが速くて短くなります。

```js run
function sameItems(a, b) {
  const sa = new Set(a);
  const sb = new Set(b);

  return sa.size === sb.size && [...sa].every((value) => sb.has(value));
}

console.log(sameItems([3, 1, 2], [1, 2, 3]));
console.log(sameItems([1, 1, 2], [1, 2, 2]));
```
```output
true
true
```

`[1, 1, 2]` と `[1, 2, 2]` が[bad:どちらも `true` になります]。
**個数まで見たいなら `Set` は使えません。**

## 共通・差分を求める

`Set` の演算が使えます（ES2025）。

```js run
const a = new Set([1, 2, 3]);
const b = new Set([2, 3, 4]);

console.log([...a.intersection(b)]);
console.log([...a.difference(b)]);
console.log([...a.union(b)]);
```
```output
[ 2, 3 ]
[ 1 ]
[ 1, 2, 3, 4 ]
```

[dim:Node 22 / Chrome 122 / Safari 17 / Firefox 127 より前では使えません。]

古い環境でも動く書き方はこちらです。

```js run
const a = [1, 2, 3];
const b = [2, 3, 4];
const sb = new Set(b);

console.log(a.filter((n) => sb.has(n)));
console.log(a.filter((n) => !sb.has(n)));
```
```output
[ 2, 3 ]
[ 1 ]
```

**`Set` にしてから `has()` で引く**のが要点です。
`b.includes(n)` と書くと、`a` の要素ごとに `b` を最後まで走査するので、
件数が増えたときに一気に遅くなります。
→ [Map と Set](/ja/javascript/reference/collection/map-set/)

## オブジェクトの配列は気をつける

```js run
const a = [{ n: 1 }];
const b = [{ n: 1 }];

console.log(a[0] === b[0]);
console.log(JSON.stringify(a) === JSON.stringify(b));
```
```output
false
true
```

見た目が同じでも[bad:別のオブジェクト]なので、`===` では一致しません。

`JSON.stringify()` で比べると通りますが、**鍵の順番に左右されます。**

```js run
console.log(JSON.stringify([{ x: 1, y: 2 }]) === JSON.stringify([{ y: 2, x: 1 }]));
```
```output
false
```

**同じ中身なのに `false` です。**

比べたいものが決まっているなら、**その値だけを取り出して比べる**のが確実です。

```js run
const a = [{ id: 1, name: 'あ' }, { id: 2, name: 'い' }];
const b = [{ id: 1, name: 'A' }, { id: 2, name: 'B' }];

const idsA = a.map((user) => user.id);
const idsB = b.map((user) => user.id);

console.log(idsA.length === idsB.length && idsA.every((id, i) => id === idsB[i]));
```
```output
true
```

**「何が同じなら同じとみなすのか」を先に決めてください。**
それが決まらないまま「配列を比べる」ことはできません。

## よくある間違い

### 長さを見ずに `every()` だけで比べる

```js bad
const a = [1, 2];
const b = [1, 2, 3];

console.log(a.every((value, i) => value === b[i]));
```
```output
true
```

**要素数が違うのに `true` です。** `a` の分だけ見て終わっているからです。

`every()` は空配列でも `true` を返します。

```js run
console.log([].every(() => false));
```
```output
true
```

「[key:すべての要素が条件を満たす]」は、要素が無ければ満たされたことになります。
**長さを先に見てください。**

### `toString()` で比べる

```js bad
console.log([1, [2]].toString() === [1, 2].toString());
```
```output
true
```

`toString()` は入れ子を[bad:平らにして繋げます]。`'1,2'` と `'1,2'` になり、
**構造が違うのに一致します。**

`JSON.stringify()` なら区別できます。

```js run
console.log(JSON.stringify([1, [2]]) === JSON.stringify([1, 2]));
```
```output
false
```

## どれを使うか

| 知りたいこと | 使うもの |
|---|---|
| 順番も含めて完全に同じか | 長さ + `every()` |
| 同じものが揃っているか（個数を無視） | `Set` の大きさと `has()` |
| 共通・差分 | `Set` の `intersection()` / `difference()` |
| 古い環境で共通・差分 | `filter()` + `Set.has()` |
| オブジェクトの配列 | **比べる値を決めてから** |

## まとめ

- 配列の `===` は[key:同じ実体か]しか見ない。**中身は見ない**
- 中身で比べるなら**長さを先に**見て、`every()` で順に比べる
- 順序を無視するなら並べ替えるか `Set`。**`Set` は個数を無視する**
- 共通・差分は `Set` の演算。古い環境なら `filter()` + `has()`
- **`JSON.stringify()` の比較は鍵の順に左右される**
- オブジェクトの配列は、**何が同じなら同じかを先に決める**
