美文网首页
Javascript数组去重

Javascript数组去重

作者: IloveData | 来源:发表于2016-09-05 12:56 被阅读0次

偶然和同事谈到面试的Javascript问题,其中基本上都会有一道问题就是数组去重,随着对于语言深入的学习,这道基础问题也有了更多的解法。

理解问题

该问题要注意

  • 两个元素通过===比较,返回true则视为相同元素,需要去重,在此基础下,1'1'是不同元素,1new Number(1)是不同元素,{}{}是不同元素(引用不同)

基本解法

方法一:遍历数组,若存在于数组,则说明是重复元素,将没有的元素放入新数组

function unique(arr) {
    var newArr = [];
    for (var i = 0, len = arr.length; i < len; i ++) {
        var item = arr[i];
        for (var k = 0, kLen = newArr.length; k < kLen; k ++) {
            if (newArr[k] === item) break;
        }
        if (k === kLen) newArr.push(item);
    }

    return newArr;
}

此方法复杂度为O(n^2),逻辑非常简单,大概的思路也如此。

进阶一下,使用indexOf方法简化

具体可以看看Javascript中的Array.prototype.indexOf()方法:

function unique(arr) {
    var newArr = [];
    for (var i = 0, len = arr.length; i < len; i ++) {
        var item = arr[i];
        (newArr.indexOf(item) === -1) && newArr.push(item);
    }
    return newArr;
}

其中(newArr.indexOf(item) === -1) && newArr.push(item)这种写法不太常见,这里也做个记录

&& operator
Logical And
Usage: expr1 && expr2
Description:
Returns expr1 if it can be converted to false; otherwise, returns expr2.
Thus, when used with Boolean values, && returns true if both operands are true; otherwise, returns false.
--- MDN

即:

if (newArr.indexOf(item) === -1) newArr.push(item)

加入filter()方法

具体方法查阅Array.prototype.filter()

function unique(arr) {
    var newArr = arr.filter(function(item, index, array){
      return array.indexOf(item) === index;
    }) 
        
    return newArr;
}

// ES6写法
const unique = (arr) => arr.filter((item, index, arr) => array.indexOf(item) === index)

简洁的多,当然这种写法考验jser对于数组相关方法的熟悉程度。

进阶解法

当考虑到算法复杂度的层面时,以上解法就显得有些平庸了,这里我们考虑几种进阶的方案。

拥抱ES6,使用SetArray.from

Set对象见这里

Array.from()方法见这里

可以看到,SetES6中内置的一个对象,是一些值的集合,可以遍历循环其中元素的插入顺序,在Set中的值可能只出现一次,在集合中是独一无二的。

Array.from()则是ES6新增的数组方法,他允许你基于array-like objects(objects with a length property and indexed elements)或者iterable obejcts(objects where you can get its elements such as Map and Set去创建一个数组。

基于以上两个方法,我们可以这样写:

function unique(arr) {
    return Array.from(new Set(arr));    // return an array created by Set
}

以上方法针对的都是原始变量,当元素为Object类型时要作何处理呢

console.log(1 === 1) // true
console.log('1' === '1')  // true
console.log({a: 1} === {a: 1})  //false

可以看出,{a: 1} === {a: 1}false,这是因为对象存储的是引用,而原始变量存储的则是

因此我们需要换一个思路去实现。

使用HashTable(哈希表)

HashTableJavascript中是一个简单的Object,他的Key永远是String类型,因此我们不能区分字符串和数字表示的相同的值,如1'1'

var hashTable = {};
hashTable[1] = true;
hashTable['1'] = true;
console.log(hashTable);
// {'1': true}

那么如果要区分开来,我们需要将Key变为唯一的,使用JSON.stringify:

var hashTable = {};
hashTable[JSON.stringify(1)] = true;
hashTable[JSON.stringify('1')] = true;
console.log(hashTable);  // {'1': true, '"1"': true}

综上,我们实现对于任何类型元素进行去重的方法:

function unique(arr) {
    var hashTable = {};

    return arr.filter(function(item) {
        var key = JSON.stringify(item);
        var match = Boolean(hashTable[key]);

        return (match ? false: hashTable[key] = true);
        })
}

阅读材料:

Array.prototype.indexOf()
Array.prototype.filter()
Set
Array.from()
JSON.stringify()
Arrow functions

相关文章

  • JavaScript数组去重算法实例

    本文主要介绍了JavaScript数组去重算法,结合实例形式总结分析了JavaScript数组去重相关的读写、遍历...

  • javascript数组去重,数组对象去重

    利用Reduce去重 function unique(arr) {var obj = {};arr = arr.r...

  • JavaScript - 数组去重

    数组去重 1.for循环 2.0 少了多少行代码~~~ 3.0 indexOf 4.0 map/forEach E...

  • javascript 数组去重

    es6数组去重的方法

  • JavaScript 数组去重

    数组去重,一般都是在面试的时候才会碰到,一般是要求手写数组去重方法的代码。如果是被提问到,数组去重的方法有哪些?你...

  • JavaScript 数组去重

    博客地址:https://ainyi.com/#/32 单数组去重 filter + indexOf() filt...

  • JavaScript数组去重

    数组去重是一个js中在面试中经常被问到的问题,被问到是因为确实能够考察一些问题。如果不使用第三方的工具库,完全使用...

  • Javascript 数组去重

    数组去重 数组去重,一般需求是给你一个数组,调用去重方法,返回数值副本,副本中没有重复元素。一般来说,两个元素通过...

  • 【JavaScript】数组去重

    话说面试常会碰到面试官会问JavaScript实现数组去重的问题,最近刚好在学习有关于JavaScript数组相关...

  • JavaScript数组去重

    当前元素的下标,和从数组里找到该元素的下标一样时,说明是第一次出现 ES6 Set类似于数组,成员值唯一,经过过滤...

网友评论

      本文标题:Javascript数组去重

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