js专题:数组去重

作者: 幻城之雪 | 来源:发表于2023-06-07 22:57 被阅读0次

最原始的方法:双层循环

var array = [1, 1, '1', '1'];

function unique(array) {
    // res用来存储结果
    var res = [];
    for (var i = 0, arrayLen = array.length; i < arrayLen; i++) {
        for (var j = 0, resLen = res.length; j < resLen; j++ ) {
            if (array[i] === res[j]) {
                break;
            }
        }
        // 如果array[i]是唯一的,那么执行完循环,j等于resLen
        if (j === resLen) {
            res.push(array[i])
        }
    }
    return res;
}

console.log(unique(array)); // [1, "1"]

在这个方法中,我们使用循环嵌套,最外层循环 array,里面循环 res,如果
array[i] 的值跟 res[j] 的值相等,就跳出循环,如果都不等于,说明元素是
唯一的,这时候 j 的值就会等于 res 的长度,根据这个特点进行判断,将值添
加进 res。看起来很简单吧,之所以要讲一讲这个方法,是因为——————兼容性好!

indexOf

我们可以用 indexOf 简化内层的循环:

var array = [1, 1, '1'];

function unique(array) {
    var res = [];
    for (var i = 0, len = array.length; i < len; i++) {
        var current = array[i];
        if (res.indexOf(current) === -1) {
            res.push(current)
        }
    }
    return res;
}
console.log(unique(array));

排序后去重

var array = [1, 1, '1'];

function unique(array) {
    var res = [];
    var sortedArray = array.concat().sort();
    var seen;
    for (var i = 0, len = sortedArray.length; i < len; i++) {
        // 如果是第一个元素或者相邻的元素不相同
        if (!i || seen !== sortedArray[i]) {
            res.push(sortedArray[i])
        }
        seen = sortedArray[i];
    }
    return res;
}

console.log(unique(array));

如果我们对一个已经排好序的数组去重,这种方法效率肯定高于使用 indexOf。

unique API

知道了这两种方法后,我们可以去尝试写一个名为 unique 的工具函数,我们根据一个参数 isSorted 判断传入的数组是否是已排序的,如果为 true,我们就判断相邻元素是否相同,如果为 false,我们就使用 indexOf 进行判断

var array1 = [1, 2, '1', 2, 1];
var array2 = [1, 1, '1', 2, 2];

// 第一版
function unique(array, isSorted) {
    var res = [];
    var seen = [];

    for (var i = 0, len = array.length; i < len; i++) {
        var value = array[i];
        if (isSorted) {
            if (!i || seen !== value) {
                res.push(value)
            }
            seen = value;
        }
        else if (res.indexOf(value) === -1) {
            res.push(value);
        }        
    }
    return res;
}

console.log(unique(array1)); // [1, 2, "1"]
console.log(unique(array2, true)); // [1, "1", 2]

优化

尽管 unqique 已经可以试下去重功能,但是为了让这个 API 更加强大,
我们来考虑一个需求:
新需求:字母的大小写视为一致,比如'a'和'A',保留一个就可以了!
虽然我们可以先处理数组中的所有数据,比如将所有的字母转成小写,然后再
传入unique函数,但是有没有方法可以省掉处理数组的这一遍循环,直接就在
去重的循环中做呢?让我们去完成这个需求:

var array3 = [1, 1, 'a', 'A', 2, 2];

// 第二版
// iteratee 英文释义:迭代 重复
function unique(array, isSorted, iteratee) {
    var res = [];
    var seen = [];

    for (var i = 0, len = array.length; i < len; i++) {
        var value = array[i];
        var computed = iteratee ? iteratee(value, i, array) : value;
        if (isSorted) {
            if (!i || seen !== computed) {
                res.push(value)
            }
            seen = computed;
        }
        else if (iteratee) {
            if (seen.indexOf(computed) === -1) {
                seen.push(computed);
                res.push(value);
            }
        }
        else if (res.indexOf(value) === -1) {
            res.push(value);
        }        
    }
    return res;
}

console.log(unique(array3, false, function(item){
    return typeof item == 'string' ? item.toLowerCase() : item
})); // [1, "a", 2]

在这一版也是最后一版的实现中,函数传递三个参数:
array:表示要去重的数组,必填
isSorted:表示函数传入的数组是否已排过序,如果为 true,将会采用更快的
方法进行去重
iteratee:传入一个函数,可以对每个元素进行重新的计算,然后根据处理的结
果进行去重
至此,我们已经仿照着 underscore 的思路写了一个 unique 函数。

相关文章

  • 数组的去重和数组中对象的去重

    数组中对象去重 方式1 jq方式 方式2 原生js方式 普通数组的去重 方式1 普通的数组去重js 方式2 Se...

  • js数组去重、对象数组去重

    普通数组去重 一、普通数组去重 方法一:遍历数组法 方法二:排序法 方法三:对象法 对象数组去重 方法一:将对象数...

  • js数组去重

    Set结构去重 ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。 向 Se...

  • JS数组去重

    方法1:两层for循环,外层循环原数组,内层循环时进行比较。 方法2:利用对象的属性不能相同的特点去重 方法3:利...

  • js数组去重

  • js数组去重

    1.利用对象的属性唯一性去重 2.利用es6的Set

  • js数组去重

  • js 数组去重

  • JS数组去重

    方法一:遍历数组,建立新数组,利用indexOf判断是否存在于新数组中,不存在则push到新数组,最后返回新数组 ...

  • js数组去重

    方法一 (es6 set方法,简单粗暴) 方法二 创建空数组,用indexOf方法检索,没有的话插入新数组中 方...

网友评论

    本文标题:js专题:数组去重

    本文链接:https://www.haomeiwen.com/subject/hcuoedtx.html