加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

数组去重

发布时间:2020-12-15 07:43:50 所属栏目:Java 来源:网络整理
导读:题目描述 编写一个Javascript函数,传入一个数组,对数组中的元素进行去重并返回一个无重复元素的数组,数组的元素可以是数字、字符串、数组和对象。举例说明: 1. 如传入的数组元素为[123,"meili","123","mogu",123],则输出:[123,"mogu"] 2. 如传入的数组

题目描述

编写一个Javascript函数,传入一个数组,对数组中的元素进行去重并返回一个无重复元素的数组,数组的元素可以是数字、字符串、数组和对象。举例说明:
1. 如传入的数组元素为[123,"meili","123","mogu",123],则输出:[123,"mogu"]
2. 如传入的数组元素为[123,[1,2,3],"2","meili"],"meili"]
3. 如传入的数组元素为[123,{a: 1},{a: {b: 1}},{a: "1"},"meili"]

第一种解法:map+Set

把数组中的对象解析成字符串的方法用的是JSON.stringify()方法

var arr1 = [123,"meili"];
        var arr2 = [123,123];
        var arr3 = [123,"meili"];

        function unique(arr) {
            var  b = arr.map(item=>{
                return JSON.stringify(item);//JSON.stringify(item)是把数组中的对象解析成字符串再比较
             })
             var c = Array.from(new Set(b));//Set(b)用来对b去重,但是去重后的结果不是我们想要的数组的形式,所以需要用 Array.from()的方法变成我们想要的数组的形式
             var d = c.map(item=>{
                return JSON.parse(item);
             })
             return  d;

        console.log(unique(arr1));
        console.log(unique(arr2));
        console.log(unique(arr3));

1.1 filter

使用filter代替map,结果出来的结果不是想要的

注意:filter返回的是filter返回的是在一定条件下返回值为true的原数组项,所以此处最适合的是map或者for循环

所以如果需要从原数组中返回满足一定条件的数组,可以使用filter。

1.2 map和filter

红宝书中是这样描述的:

  • filter()----创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
  • map()----返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。按照原始数组元素顺序依次处理元素。

1.3 map和foreach

相同点

  • 都是会遍历数组的每一个元素,
  • 同样是三个参数
  • 都是只能遍历数组

不同点

  • forEach()方法不会返回执行结果,而是undefined,红宝书中说的是没有返回值
  • 而map()方法会得到一个新的数组并返回

使用场景

  • forEach适合于你并不打算改变数据的时候,而只是想用数据做一些事情 – 比如存入数据库或则打印出来
  • map()适用于你要改变数据值的时候。不仅仅在于它更快,而且返回一个新的数组

forEach到底会不会改变原数组

1.4 Array.from

Array.from方法用于将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象(包括 ES6 新增的数据结构 Set 和 Map)

1.4.1 将两类对象转化为真正的数组

  • 类数组对象所谓类似数组的对象,本质特征只有一点,即必须有length属性

    let arrayLike = {
        '0': 'a','1': 'b','2': 'c',length: 3
    };
    
    // ES5的写法
    var arr1 = [].slice.call(arrayLike); // ['a','b','c']
    
    // ES6的写法
    let arr2 = Array.from(arrayLike); // ['a','c']

    关于call的思考

  • 只要是部署了 Iterator 接口的数据结构,Array.from都能将其转为数组。

    Array.from('hello')
    // ['h','e','l','o']
    
    let namesSet = new Set(['a','b'])
    Array.from(namesSet) // ['a','b']

    补充:扩展运算符(...)也可以将某些数据结构转为数组。扩展运算符背后调用的是遍历器接口(Symbol.iterator),因此只要具有 Iterator 接口的对象,都可以使用扩展运算符

    let nodeList = document.querySelectorAll('div');
    let array = [...nodeList];

    上面代码中,querySelectorAll方法返回的是一个NodeList对象。它不是数组,而是一个类似数组的对象。这时,扩展运算符可以将其转为真正的数组,原因就在于NodeList对象实现了 Iterator

    • 比如 Map 结构是具有 Iterator 接口的对象,可以使用扩展运算符
    let map = new Map([
      [1,'one'],[2,'two'],[3,'three'],]);
    
    let arr = [...map.keys()]; // [1,3]
    • Generator 函数运行后,返回一个遍历器对象,因此也可以使用扩展运算符。
    const go = function*(){
      yield 1;
      yield 2;
      yield 3;
    };
    
    [...go()] // [1,3]

    上面代码中,变量go是一个 Generator 函数,执行后返回的是一个遍历器对象,对这个遍历器对象执行扩展运算符,就会将内部遍历得到的值,转为一个数组。

    • 如果对没有 Iterator 接口的对象,使用扩展运算符,将会报错。
    const obj = {a: 1,b: 2};
    let arr = [...obj]; // TypeError: Cannot spread non-iterable object
  • 本身是数组的话

    Array.from([1,3])
    // [1,3]

1.4.2 Array.from还可以接受第二个参数

作用类似于数组的map方法,用来对每个元素进行处理,将处理后的值放入返回的数组。

Array.from(arrayLike,x => x * x);
// 等同于
Array.from(arrayLike).map(x => x * x);

Array.from([1,(x) => x * x)
// [1,4,9]

1.4.3 如果map函数里面用到了this关键字,还可以传入Array.from的第三个参数,用来绑定this

1.4.4 将字符串转为数组,然后返回字符串的长度

function countSymbols(string) {
  return Array.from(string).length;
}

第二种解法 :双重遍历

思想:通过拿出一个元素和剩下的元素依次比较,如果全部不相等则证明此元素为唯一

var arr1 = [123,"meili"];
        var arr3 = [123,123];
        var arr2 = [123,"meili"];

        function unique(arr) {
            let b=[]
            for(let i=0;i<arr.length;i++){
                let unexit=true
                for(let j=i+1;j<arr.length;j++){
                    if(JSON.stringify(arr[i])===JSON.stringify(arr[j])){
                        unexit=false
                        break
                    }
                    else{
                        unexit=true
                    }
                }
                if(unexit){
                    b.push(arr[i])
                }
            }
            return b
            
        }

        console.log(unique(arr1));
        console.log(unique(arr2));
        console.log(unique(arr3));

缺点:顺序会改变

第三种解法:Object.keys():存在唯一性

var arr1 = [123,"meili"];

        function unique(arr) {
            let b=[]
            let hash={}
            for(let i=0;i<arr.length;i++){
                if(!hash[JSON.stringify(arr[i])]){
                    hash[JSON.stringify(arr[i])]=true
                    b.push(arr[i])
                }
            }
            return b    
        }

        console.log(unique(arr1));
        console.log(unique(arr2));
        console.log(unique(arr3));

这三种方法都可以实现对象去重,第二种存在一些缺点,顺序会改变。

参考:https://www.aspzz.cn/article/134411.htm

http://es6.ruanyifeng.com/#docs/set-map#Map

https://juejin.im/post/5ca7514a6fb9a05e790a46a4

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读