本文总结了JavaScript去重的多种方式,各有优缺点,根据需求合理使用吧。
- 使用
for循环和indexOf方法,复杂度 O(n^2)
function uniqueArray(arr) {
const result = []
for (let i = 0; i < arr.length; i++) {
if (result.indexOf(arr[i]) === -1) {
result.push(arr[i])
}
}
return result
}- 使用
for循环和对象,复杂度 O(n^2)
function uniqueArray(arr) {
const result = []
const obj = {}
for (let i = 0; i < arr.length; i++) {
if (!obj[arr[i]]) {
result.push(arr[i])
obj[arr[i]] = true
}
}
return result
}- 使用
filter方法和indexOf方法,复杂度 O(n^2)
function uniqueArray(arr) {
return arr.filter((item, index, arr) => arr.indexOf(item) === index)
}- 使用
filter方法和对象,复杂度 O(n)
function uniqueArray(arr) {
const obj = {}
return arr.filter((item) => obj.hasOwnProperty(item) ? false : (obj[item] = true))
}- 使用
Set数据结构,复杂度 O(n)
// 使用解构 + Set
function uniqueArray(arr) {
return [...new Set(arr)]
}" title="" data-bs-original-title="复制" aria-label="复制"></button>
</div>
function uniqueArray(arr) {
return Array.from(new Set(arr))
}
// 使用解构 + Set
function uniqueArray(arr) {
return [...new Set(arr)]
}
- 使用
Map数据结构,复杂度 O(n)
<button type="button" class="btn btn-dark far fa-copy rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="function uniqueArray(arr) {
const map = new Map();
const result = [];
for (let i = 0; i < arr.length; i++) {
if (!map.has(arr[i])) {
map.set(arr[i], true);
result.push(arr[i]);
}
}
return result;
}
// or
function uniqueArray(arr) {
const map = new Map();
return arr.filter(function(item) {
return !map.has(item) && map.set(item, true);
});
}" title="" data-bs-original-title="复制" aria-label="复制"></button>
</div>
function uniqueArray(arr) {
const map = new Map();
const result = [];
for (let i = 0; i < arr.length; i++) {
if (!map.has(arr[i])) {
map.set(arr[i], true);
result.push(arr[i]);
}
}
return result;
}
<span class="hljs-comment">// or</span>
<span class="hljs-keyword">function</span> <span class="hljs-title function_">uniqueArray</span>(<span class="hljs-params">arr</span>) {
<span class="hljs-keyword">const</span> map = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Map</span>();
<span class="hljs-keyword">return</span> arr.<span class="hljs-title function_">filter</span>(<span class="hljs-keyword">function</span>(<span class="hljs-params">item</span>) {
<span class="hljs-keyword">return</span> !map.<span class="hljs-title function_">has</span>(item) && map.<span class="hljs-title function_">set</span>(item, <span class="hljs-literal">true</span>);
});
}</pre><ul><li>使用双重循环和 <code>splice</code> 方法,复杂度 O(n^2)</li></ul><div class="widget-codetool" style="display: none;">
<div class="widget-codetool--inner">
<button type="button" class="btn btn-dark far fa-copy rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="function uniqueArray(arr) {
for (var i = 0; i < arr.length; i++) {
for (var j = i + 1; j < arr.length; j++) {
if (arr[i] === arr[j]) {
arr.splice(j, 1);
j--;
}
}
}
return arr;
}" title="" data-bs-original-title="复制" aria-label="复制"></button>
</div>
function uniqueArray(arr) {
for (var i = 0; i < arr.length; i++) {
for (var j = i + 1; j < arr.length; j++) {
if (arr[i] === arr[j]) {
arr.splice(j, 1);
j--;
}
}
}
return arr;
}- 使用排序和双指针
使用排序和双指针可以实现 O(nlogn) 的时间复杂度。先对数组进行排序,然后使用双指针遍历数组,如果左指针和右指针指向的值相同,就把右指针向右移动,直到找到不同的值,然后把左指针向右移动,继续遍历。
function uniqueArray(arr) {
arr.sort();
var left = 0, right = 1;
var result = [];
while (right <= arr.length) {
if (arr[left] === arr[right]) {
right++;
} else {
result.push(arr[left]);
left = right;
right++;
}
}
return result;
}- 使用
reduce方法和includes,复杂度 O(n^2)
function uniqueArray(arr) {
return arr.reduce(function(prev, cur) {
if (!prev.includes(cur)) {
prev.push(cur);
}
return prev;
}, []);
}- 使用递归和
includes,复杂度 O(n^2)
function uniqueArray(arr) {
if (arr.length === 1) {
return arr;
} else {
const first = arr[0];
const rest = uniqueArray(arr.slice(1));
if (rest.includes(first)) {
return rest;
} else {
return [first].concat(rest);
}
}
}- 双层循环,复杂度 O(n^2)
function uniqueArray(arr) {
var result = [];
for (var i = 0; i < arr.length; i++) {
for (var j = 0; j < result.length; j++) {
if (arr[i] === result[j]) {
break;
}
}
if (j === result.length) {
result.push(arr[i]);
}
}
return result;
}