DrillLab
第 22 / 105 道22 / 105 · #286

Set vs Array

Set vs Array

先自己答,再往下看Answer it yourself first

一句话:Set元素唯一、查找是 O(1)、没有下标; 数组允许重复、有顺序和下标、includes 是 O(n)。

ArraySet
重复元素允许自动去重
查「在不在」includes O(n)has O(1)
下标访问arr[0]没有
取长度lengthsize
map / filter没有,要先转数组

什么时候用 Set:去重、以及在循环里反复判断「见过没有」—— 后者是性能差别最大的场景, 数组的 includes 会让复杂度从 O(n) 变 O(n²)。

会追问:「Set 去重能去掉重复的对象吗?」——不能。Set 用的是SameValueZero(≈===), 两个内容一样的对象是不同的引用。 要按内容去重得自己用Map 按某个 key 存。
NaN 呢?」—— Set 里NaN 只会存一个, 这是 SameValueZero=== 唯一的差别。

In one line: a Set holds unique elements, checks membership in O(1), and has no indices; an array allows duplicates, has order and indices, and its includes is O(n).

ArraySet
DuplicatesAllowedDropped automatically
“Is it in there?”includes O(n)has O(1)
Index accessarr[0]None
Lengthlengthsize
map / filterYesNo — convert to an array first

When to use a Set: deduping, and answering “have I seen this before?” inside a loop — the second is where the performance gap is biggest, because an array includes turns O(n) into O(n²).

Follow-up: “Can a Set dedupe identical objects?” — no. A Set uses SameValueZero (≈===), and two objects with the same contents are still two different references. To dedupe by content, key them yourself in a Map.
“What about NaN?” — a Set stores NaN only once. That is the only difference between SameValueZero and ===.

JavaScriptSet 的两个真实用途Two real uses for Set示意Illustrative
1// 去重一行
2const unique = [...new Set([1, 2, 2, 3])]; // [1, 2, 3]
3
4// 循环里判重:O(n²) -> O(n)
5const seen = new Set();
6for (const x of list) {
7 if (seen.has(x)) continue; // O(1),换成 arr.includes 就是 O(n)
8 seen.add(x);
9}
10
11// 去不掉对象
12new Set([{ id: 1 }, { id: 1 }]).size; // 2 ← 引用不同
13
14// 按内容去重要用 Map
15const byId = new Map(items.map((i) => [i.id, i]));
16const deduped = [...byId.values()];
1// Dedupe in one line
2const unique = [...new Set([1, 2, 2, 3])]; // [1, 2, 3]
3
4// Checking for duplicates in a loop: O(n²) -> O(n)
5const seen = new Set();
6for (const x of list) {
7 if (seen.has(x)) continue; // O(1); arr.includes here would be O(n)
8 seen.add(x);
9}
10
11// It cannot dedupe objects
12new Set([{ id: 1 }, { id: 1 }]).size; // 2 ← different references
13
14// To dedupe by content, use a Map
15const byId = new Map(items.map((i) => [i.id, i]));
16const deduped = [...byId.values()];