JS数组去重的n种解法

作者: 公子七 | 来源:发表于2017-08-13 18:28 被阅读169次

已知排序的array,或者不在乎去重之后的结果顺序

Solution 1
可以做一次循环,判断当前的item是否等于前面那个item,如果不等于或不存在前面的item,就pushresult中。
时间复杂度:O(nlogn)
空间复杂度:O(n)

Array.prototype.uniq = function () {
    if (!this.length || this.length == 0) return this;
    this.sort();
    var res = [this[0]];
    for (var i = 1; i < this.length; i++) {
        if (this[i] != this[i - 1]) res.push(this[i]);
    }
    return res;
}

Solution 2
采用两个指针lr,记录不重复元素的位置,rl的下一个开始遍历数组,如果r位置的数字等于l位置的数字,说明该数字重复出现,不予处理;如果r位置的数字不等于l位置的数字,说明该数字没有重复,需要放到l的下一位置,并使l1.
时间复杂度:O(nlogn)
空间复杂度:O(1)

Array.prototype.uniq = function () {
    if (!this.length || this.length == 0) return this;
    this.sort();
    var left = 0, right;
    for (right = left + 1; right < this.length; right++) {
        if (this[left] != this[right]) {
            this[++left] = this[right];
        }
    }
    return this.slice(0, left + 1);
}

Solution 3
数组先排序,比较俩数组一头一尾进行去重。

Array.prototype.uniq = function () {
    var res = [], end;
    this.sort();
    end = this[0], res.push(this[0]);
    for (var i = 1; i < this.length; i++) {
        if (this[i] != end) {
            res.push(this[i]);
            end = this[i];
        }
    }
    return res;
}

如果数组顺序杂乱

Solution 1
可以做一次循环,用一个对象标记该item是否存在。如果不存在,就pushresult中。这里使用一个hashtable的结构记录已有的元素,这样就可以避免内层循环。不过,假如数组非常庞大,这种做法的性能会差。

Array.prototype.uniq = function () {
    var hash = {}, result = [], item;
    for (var i = 0; i < this.length; i++) {
        item = this[i]; 
        var key = Object.prototype.toString.call(item) + item;
        if (!hash[key]) {
            hash[key] = true;
            result.push(item);
        }
    }
    return result;
}

注意jshash的键值是以字符存储的,所以会自动将数组元素转为字符型,因此作为hash索引时需要加上类型,否则无法区分数字1和字符1
Solution 2
遍历数组,建立新数组,利用indexOf判断是否存在于新数组中,不存在则push到新数组,最后返回新数组。时间复杂度为O(n^2)。

Array.prototype.uniq = function () {
    var ret = [];
    for (var i = 0; i < this.length; i++) {
        if (ret.indexOf(this[i]) == -1) {
            ret.push(arr[i]);
        }
    }
    return ret;
}

Solution 3
遍历数组,利用object对象保存数组值,判断数组值是否已经保存在object中,未保存则push到新数组并用object[arrayItem] = 1的方式记录保存。

Array.prototype.uniq = function () {
    var ret = [], tmp = [];
    for (var i = 0; i < this.length; i++) {
        if (!tmp[arr[i]]) {
            tmp[arr[i]] = 1;
            ret.push(arr[i]);
        }
    }
    return ret;
}

Solution 4
数组下标判断法。遍历数组。利用indexOf判断元素的值是否与当前元素索引相等,如相等则加入。

Array.prototype.uniq = function () {
    var res = [];
    var me = this;
    me.forEach(function (val, index) {
        if (me.indexOf(val) == index) 
           res.push(val);
    })
    return res;
}

可以用filter过滤。

Array.prototype.uniq = function () {
    var me = this;
    var res = me.filter(function (x, index) {
        return me.indexOf(x) == index;
    }); 
    return res;
}

Solution 5
将原数组中重复元素的最后一个元素放入结果数组中。

Array.prototype.uniq = function () {
    var res = [];
    for (var i = 0; i < this.length; i++) {
        for (var j = i + 1; j < this.length; j++) {
            if (this[i] == this[j]) j = ++i;
        }
        res.push(this[i]);
    }
    return res;
}

ES6

function unique(arr) {
  return Array,from(new Set(arr));
}

相关文章

  • JS数组去重的n种解法

    已知排序的array,或者不在乎去重之后的结果顺序 Solution 1可以做一次循环,判断当前的item是否等于...

  • js中数组去除重复的元素

    js数组去重 去除数组中重复的元素,用js实现一般来说有三种较常用的方式。 function 1 时间复杂度O(n...

  • 又是老话题,数组去重

    昨天看到一个讨论数组去重的文章,觉得代码可以再简洁一点。 普通解法 时间复杂度:O(n^2) 高效解法 把obje...

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

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

  • js数组去重的N种方法

    对于数组去重我们有n种方法可以实现。 es5实现方法for循环+indexOf function unique(...

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

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

  • js数组去重

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

  • JS数组去重

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

  • js数组去重

  • js数组去重

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

网友评论

    本文标题:JS数组去重的n种解法

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