方法一
无需思考,我们可以得到 O(n^2) 复杂度的解法。定义一个变量数组 res 保存结果,遍历需要去重的数组,如果该元素已经存在在 res 中了,则说明是重复的元素,如果没有,则放入 res 中。
function unique(a) {
var res = [];
for (var i = 0, len = a.length; i < len; i++) {
var item = a[i];
for (var j = 0, jLen = res.length; j < jLen; j++) {
if (res[j] === item)
break;
}
if (j
JavaScript数组去重是一个常见的编程问题,特别是在处理数据集合时。以下将详细讲解6种不同的方法来实现JavaScript数组去重,并分析其效率和适用场景。
**方法一:双重循环检查**
这是最直观的方法,通过外层循环遍历数组,内层循环检查当前元素是否已存在于结果数组中。这种方法的时间复杂度为O(n^2),效率较低,但实现简单。
```javascript
function unique(a) {
var res = [];
for (var i = 0, len = a.length; i < len; i++) {
var item = a[i];
for (var j = 0, jLen = res.length; j < jLen; j++) {
if (res[j] === item) break;
}
if (j === jLen) res.push(item);
}
return res;
}
```
**方法二:利用`indexOf`**
ES5引入的`Array.prototype.indexOf`方法可以用来查找元素在数组中的索引,若不存在则返回-1。通过检查索引是否为-1来决定是否添加元素到结果数组,简化了代码,但时间复杂度依然是O(n^2)。
```javascript
function unique(a) {
var res = [];
for (var i = 0, len = a.length; i < len; i++) {
var item = a[i];
(res.indexOf(item) === -1) && res.push(item);
}
return res;
}
```
**方法三:结合`sort`和`filter`**
对数组进行排序后,相同元素会相邻,然后通过`filter`检查相邻元素是否相同。但这不适用于包含字符串或对象的情况,因为字符串'1'和数字1在排序后会被视为相等。
```javascript
function unique(a) {
return a.concat().sort().filter(function(item, pos, ary) {
return !pos || item != ary[pos - 1];
});
}
```
**方法四:使用`Object`作为哈希表**
创建一个空对象,用数组元素作为键,值无所谓。如果元素已存在,说明是重复的,否则将其添加到结果数组。这种方法效率较高,时间复杂度为O(n),但不适用于不可哈希的元素(如对象)。
```javascript
function unique(a) {
var obj = {};
var res = [];
for (var i = 0, len = a.length; i < len; i++) {
var item = a[i];
if (!obj[item]) {
obj[item] = true;
res.push(item);
}
}
return res;
}
```
**方法五:使用`Set`**
ES6引入的`Set`数据结构具有自动去重功能,可以方便地实现数组去重,但不是所有环境都支持。
```javascript
function unique(a) {
return [...new Set(a)];
}
```
**方法六:使用`reduce`**
`reduce`函数可以将数组折叠成一个单一的值,这里我们可以将结果积累在一个数组中,同时检查元素是否已存在。
```javascript
function unique(a) {
return a.reduce((prev, cur) => prev.includes(cur) ? prev : [...prev, cur], []);
}
```
每种方法都有其优缺点,实际应用中应根据数组内容、性能需求以及浏览器/运行环境的兼容性来选择合适的方法。例如,对于大型数据集,优先考虑使用哈希表(方法四)或`Set`(方法五),而对于小规模数据和兼容性要求不高的情况,其他方法也是可行的。