数组去重

```js // 数组去重方法总结 // v1. 双层循环去重 function unique(arr) { let res = []; // 外层循环遍历原始数组 for (var i = 0, arrLen = arr.length; i < arrLen; i++) { // 内层循环遍历res数组 for (var j = 0, resLen = res.length; j < resLen; j++) { if (arr[i] === res[j]) { break; } } // 关键点:遍历完毕之后,如果arr[i]是唯一的,那么必定满足j===resLen if (j === resLen) { res.push(arr[i]); } } return res; } // 优点: 兼容性好

// v2. indexOf去重 function unique(arr) { var res = []; for (var i = 0, len = arr.length; i < len; i++) { var cur = arr[i]; if (res.indexOf(cur) === -1) { res.push(cur); } } return res; } // 优点:使用indexOf可以简化内层循环

// v3. 先排序,然后去重 function unique(arr){ var res = []; // 排序之后的数组 var sortedArr = arr.concat().sort(); // seen表示的是当前的比较项 var seen; // v1 /for (var i = 0, len = sortedArr.length; i < len; i++) { // 从第一个元素开始,比较相邻的元素是否相同 if (!i || seen !== sortedArr[i]) { res.push(sortedArr[i]); } seen = sortedArr[i]; }/

// v2
for (var i = 0, len = sortedArr.length; i < len; i++) {
    // 最后一个和undefined比较
    if (sortedArr[i] !== sortedArr[i+1]) {
        res.push(sortedArr[i]);
    }
}
return res;

}

// v4. 封装一个unique的API【重点掌握】 function unique(arr, isSorted){ var res = []; var seen = [];

for (var i = 0, len = arr.length; i < len; i++) {
    var value = arr[i];
    // 根据是否排序选择去重方式
    if (isSorted) {
        // 这个排序方法要学会
        if (!i || seen !== value) {
            res.push(value);
        }
        seen = value;
    }
    else if (res.indexOf(value) === -1) {
        res.push(value);
    }
}
return res;

}

// TODO: 如何把字母的大小写视为一致,比如'a'和'A',保留一个就可以了? // v5: 去重API增强 /**

  • 去重API增强
  • @param arr 表示要去重的数组,必填
  • @param isSorted 表示函数传入的数组是否已排过序,如果为 true,将会采用更快的方法进行去重
  • @param iteratee 传入一个函数,可以对每个元素进行重新的计算,然后根据处理的结果进行去重
  • @return {Array} */ function unique(arr, isSorted, iteratee){ var res = []; var seen = [];

    for (var i = 0, len = arr.length; i < len; i++) {

     var value = arr[i];
     // 处理iteratee参数
     var computed = iteratee ? iteratee(value, i, arr) : value;
     if (isSorted) {
         if (!i || seen !== value) {
             res.push(value);
         }
         // 更新为最新的computed数据(是经过iteratee这个函数处理之后的结果)
         seen = computed;
     }
     else if (iteratee) {
         // 处理iteratee的核心逻辑
         if (seen.indexOf(computed) === -1) {
             // seen里面放的是转换处理之后的数值
             seen.push(computed);
             // 结果里面放入的始终是数组的原始值,而不是经过转换之后的数值
             res.push(value);
         }
     } else if (res.indexOf(value) === -1) {
         // 常规去重方法
         res.push(value);
     }
    

    } return res; }

// TODO: 使用filter函数简化外层循环? // v6. filter简化去重逻辑 // 使用indexOf简化 function unique(arr){ var res = arr.filter(function (item, index, self) { // indexOf实际上找到的是第一次出现的位置 return self.indexOf(item) === index; }); return res; }

// 使用排序去重的方法 function unique(arr) { return arr.concat().sort().filter(function (item, index, self) { // 后面的一项和前面的项进行比较 return !index || item !== self[index - 1]; }); }

// v7. 使用Object键值对去重(推荐使用,可以去重所有的数据类型) function unique(arr) { var obj = {}; var res = arr.filter(function (item) { // 问题1: 无法区分1和'1' // return obj.hasOwnProperty(item) ? false : (obj[item] = true);

    // 问题2: 无法区分{value: 1}和{value: 2}
    // { number1: true,
    //   stringa: true,
    //   stringA: true,
    //   number2: true,
    //   stringb: true,
    //   stringc: true,
    //   number3: true }
    // return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true);


    // 最终解决方案:使用JSON.stringfy, 先把对象序列化处理
    let temp = typeof item + JSON.stringify(item);
    return obj.hasOwnProperty(temp) ? false : (obj[temp] = true);
});
console.log('obj now:', obj)
return res;

}

// v8: ES6去重大法 function unique(arr){ return Array.from(new Set(arr)); } // 代码简化1 function unique(arr){ return [...new Set(arr)]; } // 代码简化2 var unique = (a) => [...new Set(a)];

// 使用Map去重 function unique(arr){ const seen = new Map(); return arr.filter(a => !seen.has(a) && seen.set(a, 1)); }

console.log(unique([1, 2, 3, 2, '1'])) console.log(unique([1, '1', 2, 3], true)) console.log(unique([1, 1, 'a', 'A', 2, 'b', 'c', 3, '1', {value : 1}, {value: 2}, {value: 1}], false, function (item, index, arr) { return typeof item === 'string' ? item.toLowerCase() : item; }))

var array = [1, 1, '1', '1', null, null, undefined, undefined, new String('1'), new String('1'), /a/, /a/, NaN, NaN]; console.log(unique(array));

```

results matching ""

    No results matching ""