资讯专栏INFORMATION COLUMN

js--数组hash法去重引发的json键名的思考

sarva / 576人阅读

摘要:中的数组去重问题,被讨论都快烂掉了。,法,根据对象的属性不存在相同的特点,有点类似方法。同理这四个值都会被认为是一样的而被去重。

js中的数组去重问题,被讨论都快烂掉了。网上也有很多方法,不过都大同小异,复制来复制去的。
当然这里不是讨论我是不是有什么新方法了,没有,只是在实践的时候发现一些问题,值得拿出来说说!
去重的思路有几种

1,第一个与后面所有的比较,发现重复的就删除掉,再取第二个与后面的比较,以此类推!
2,先排序,比较相邻的。
3,创建临时数组,原数组一个一个往里塞,若已存在就不塞了。
4,hash法,根据对象的属性不存在相同的特点,有点类似方法3。
….

当然这些具体代码网上很多,不一一列举!下面来探讨的是其中被人们忽略的一些问题。

方法1的代码如下

function arrayUnique(arr){ 
    for (var i=0;i‹arr.length;i++){
        for (var j=i+1;j‹arr.length-1;j++){
            if ( arr[j] === arr[i] ){
                arr.splice(j,1);
                j--;
            }
        }

    }
    return arr;
}

方法4的hash方法如下

function arrayUnique2(arr){
    var hash = {};
    var temp = [];
    for (var i=0;i‹arr.length;i++){
        if ( !hash[arr[i]] ){
            hash[arr[i]] = true;
            temp.push(arr[i]);
        }
    }
 /*
  for (var prop in hash){
   console.log(prop+"----"+typeof(prop))
 }
 */
    return temp;
}

虽然hash方法拥有非常搞的效率,但是存在一些问题,因为javascript中的数组是可以存储任意数据类型的值,就是可以是数字、字符串、或者数组、对象、函数等等。

实际测试中确实可以去除长得一样的数组或者对象,比如如下arr中的第四和第五个[1,2]会被去重,但问题来了。

var aa = "aa",bb = "bb";
var arr = [
    1,"1","abc",[1,2],[1,2],["1","2"],"1,2",["aa","bb"],[aa,bb],document,"[object HTMLDocument]",function (){return 1},function (){return 1;}
]
console.log(arrayUnique2(arr));//[1,"abc",[1,2],["aa","bb"],document,function (){return 1},function (){return 1;}]

如果两个对象的引用不同即使长得一样也不是全等的,这个我们知道,也可以说去掉长得相同的两个元素。

于是我将hash对象的属性跟属性的数据类型在函数中输出出来,发现对象属性或json键名的数据类型都是字符串类型的,并且每个被添加的属性,会被先隐式调用toString方法,即DOM中的document对象,变成对象的属性即json的键名的时候,隐式调用toString方法,这样就和"[object HTMLDocument]’是一样的了,数组去重的话,后面字符串类型的[object HTMLDocument]会被去掉。

同理[1,2],[1,2],[‘1′,’2′],’1,2’这四个值都会被认为是一样的而被去重。

数组最后面的两个函数,因为在后面的函数里加了个分号,否则也是相同。

所以会有这样的结论,在使用hash方法的时候,数组元素变成对象属性名或者json键名的时候,数据会先隐式调用toString方法变成字符串,然后成为对象的属性。而这样的后果就是,只要两个元素各自调用toString方法后的字符串相等,两个值遍认为是相同,即使两个值根本不想等。

所以这种hash去重的方法有局限性,即在去除所有值的数据类型相同的情况下,他是效率很高很好用,但是数据类型不同的情况下。还是老老实实用其他方法比较吧。(当然一般后端传到前端的数据,数据类型一般都是相同的。)

以上就是我对去重中遇到问题的一些思考,希望对大家有帮助,网上的东西,不能盲目拿来就用,要有自己的思考。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/82133.html

相关文章

  • 深入理解:ES6中Set和Map数据结构,Map与其它数据结构互相转换

    摘要:学习笔记工作中常用到的语法只是简单提及和,今天有空于是写了这篇文章深入理解中的和数据结构,与其它数据结构的互相转换。的提供了新的数据结构。本身是一个构造函数,用来生成数据结构。 文中的内容主要是来自于阮一峰的《ES6标准入门》(第三版)。《学习ES6笔记──工作中常用到的ES6语法》只是简单提及Set和Map,今天有空于是写了这篇文章──《深入理解:ES6中的Set和Map数据结构,M...

    Cristalven 评论0 收藏0
  • 【重温基础】11.Map和Set对象

    摘要:本文是重温基础系列文章的第十一篇。返回一个布尔值,表示该值是否为的成员。使用回调函数遍历每个成员。与数组相同,对每个成员执行操作,且无返回值。 本文是 重温基础 系列文章的第十一篇。 今日感受:注意身体,生病花钱又难受。 系列目录: 【复习资料】ES6/ES7/ES8/ES9资料整理(个人整理) 【重温基础】1.语法和数据类型 【重温基础】2.流程控制和错误处理 【重温基础】3....

    meteor199 评论0 收藏0
  • ES6学习之 -- Set数据结构

    摘要:类似于数组,但是中不存在重复元素。可以接受一个数组或者其他具有接口的数据结构作为参数从上面的代码可以看出有去重的功能。去重还有另一个方法将数据结构的数据转换成数组。清除实例的指定成员。返回一个布尔值,表示某个值是否在实例之中。 Set Set类似于数组,但是Set中不存在重复元素。Set可以接受一个数组(或者其他具有itarable接口的数据结构)作为参数 const set = ne...

    wawor4827 评论0 收藏0
  • ES6新增Set、Map数据结构

    摘要:数据类型基本用法提供了一种类似于数组的新的数据结构。实例属性和方法本身是一个构造函数,用来生成数据结构。返回一个布尔值,表示该值是否为的成员。任何具有接口且每个成员都是一个双元素的数组的数据结构都可以当作构造函数的参数。 Set数据类型 基本用法 ES6 提供了一种类似于数组的新的数据结构 Set。它的成员的值都是唯一的,没有重复的值。 const s = new Set(); [2...

    lentoo 评论0 收藏0
  • JS数据结构与算法_集合&字典

    摘要:上一篇数据结构与算法链表写在前面说明数据结构与算法系列文章的代码和示例均可在此找到一集合集合数据结构集合是一种包含不同元素的数据结构。集合中的元素成为成员。 上一篇:JS数据结构与算法_链表 写在前面 说明:JS数据结构与算法 系列文章的代码和示例均可在此找到 一、集合Set 1.1 集合数据结构 集合set是一种包含不同元素的数据结构。集合中的元素成为成员。集合的两个最重要特性是:...

    sf_wangchong 评论0 收藏0

发表评论

0条评论

sarva

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<