配列同士を === で比べても中身は見ません。中身が同じか調べる方法、順序を無視して比べる方法、共通・差分の求め方、オブジェクトの配列で気をつけることまで実行して確かめます。
答え
=== は使えません。 中身ではなく「同じ実体か」を見るからです。
example.js
const a = [1, 2, 3];
const b = [1, 2, 3];
console.log(a === b);
出力書き換えて実行できます
false
example.js
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]));
出力書き換えて実行できます
true
false
false
中身で比べるなら、長さと要素を順に見ます。
example.js
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()));
出力書き換えて実行できます
false
true
example.js
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]));
出力書き換えて実行できます
true
true
長さを先に見るのが要点です。見ないと、短いほうを長いほうと比べたときに通ってしまいます。
順序を無視して比べる
「同じものが揃っているか」だけを見たいなら、並べ替えてから比べます。
example.js
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)]);
出力書き換えて実行できます
[ 2, 3 ]
[ 1 ]
[ 1, 2, 3, 4 ]
example.js
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)));
出力書き換えて実行できます
[ 2, 3 ]
[ 1 ]
[...a] で複製してから並べ替えています。
a.sort() と書くと元の配列が変わります。
→ sort() と toSorted()
重複を気にしないなら Set のほうが速くて短くなります。
example.js
const a = [{ n: 1 }];
const b = [{ n: 1 }];
console.log(a[0] === b[0]);
console.log(JSON.stringify(a) === JSON.stringify(b));
出力書き換えて実行できます
false
true
example.js
console.log(JSON.stringify([{ x: 1, y: 2 }]) === JSON.stringify([{ y: 2, x: 1 }]));
出力書き換えて実行できます
false
[1, 1, 2] と [1, 2, 2] がどちらも true になります。
個数まで見たいなら Set は使えません。
共通・差分を求める
Set の演算が使えます(ES2025)。
example.js
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]));
出力書き換えて実行できます
true
javascript
const a = [1, 2];
const b = [1, 2, 3];
console.log(a.every((value, i) => value === b[i]));
true
Node 22 / Chrome 122 / Safari 17 / Firefox 127 より前では使えません。
古い環境でも動く書き方はこちらです。
example.js
console.log([].every(() => false));
出力書き換えて実行できます
true
javascript
console.log([1, [2]].toString() === [1, 2].toString());
true
Set にしてから has() で引くのが要点です。
b.includes(n) と書くと、a の要素ごとに b を最後まで走査するので、
件数が増えたときに一気に遅くなります。
→ Map と Set
オブジェクトの配列は気をつける
example.js
console.log(JSON.stringify([1, [2]]) === JSON.stringify([1, 2]));
出力書き換えて実行できます
false
見た目が同じでも別のオブジェクトなので、=== では一致しません。
JSON.stringify() で比べると通りますが、鍵の順番に左右されます。
同じ中身なのに false です。
比べたいものが決まっているなら、その値だけを取り出して比べるのが確実です。
「何が同じなら同じとみなすのか」を先に決めてください。
それが決まらないまま「配列を比べる」ことはできません。
よくある間違い
長さを見ずに every() だけで比べる
要素数が違うのに true です。 a の分だけ見て終わっているからです。
every() は空配列でも true を返します。
「すべての要素が条件を満たす」は、要素が無ければ満たされたことになります。
長さを先に見てください。
toString() で比べる
toString() は入れ子を平らにして繋げます。'1,2' と '1,2' になり、
構造が違うのに一致します。
JSON.stringify() なら区別できます。
どれを使うか
| 知りたいこと |
使うもの |
| 順番も含めて完全に同じか |
長さ + every() |
| 同じものが揃っているか(個数を無視) |
Set の大きさと has() |
| 共通・差分 |
Set の intersection() / difference() |
| 古い環境で共通・差分 |
filter() + Set.has() |
| オブジェクトの配列 |
比べる値を決めてから |
まとめ
- 配列の
=== は同じ実体かしか見ない。中身は見ない
- 中身で比べるなら長さを先に見て、
every() で順に比べる
- 順序を無視するなら並べ替えるか
Set。Set は個数を無視する
- 共通・差分は
Set の演算。古い環境なら filter() + has()
JSON.stringify() の比較は鍵の順に左右される
- オブジェクトの配列は、何が同じなら同じかを先に決める