是否存在通用的数组去重方法?

数组去重,很多时候都会用到,在具体项目中因为场景确定,很容易写出一个简单的去重方法,但大多是否具有针对性,没法适用于各类,一劳永逸
当然此处的场景所说的去重指的是去除内容大致相同的数据,不管是否同一个引用

如下这段代码,如果希望输出的是 [[1],{a:2},{a:1},[2]]

let obj = {a:1};let arr = [2];let test = [ [1], [1], {a:2}, {a:2}, obj, obj, arr, arr ];Array.prototype.unique = function(){
  ...
}console.log(test.unique());

通常我们利用SetArray互转实现去重,但是该方式在判断引用类型时,并没那么给力,只有相同的引用才会被判定为相等。

console.log([...new Set(test)]);
// [[1],[1],{a:2},{a:2}, {a:1}, [2]];

如果采用对象的方式,对付普通的数据还好,碰上这种情况也是无能为力

Array.prototype.unique = function() {  var res = [];  var json = {};  for(var i = 0; i < this.length; i++){    if(!json[this[i]]){
      res.push(this[i]);
      json[this[i]] = true;
    }
  }  return res;
}
console.log(test.unique());// [[1],{a:2},[2]] 非常神奇的是{a:1}竟然不见了

当然,如果采用极端点的方式只对引用类型的值先JSON.string(),再来做对比,好像可以,准确的说对简单且狭义的对象类型有效,因为File、Stack、HTMLElement、class、functionObject类型的等值判断没有json数据或字符串那般简单。


神不在的星期二
浏览 554回答 2
2回答

莫回无

首先谈下我的理解,不可能有一劳永逸的方法。同意楼上去除复杂引用类型本身就是一个高度自定化的功能,需要自身去定义,按你的说法,1.待去重数组内的类型是不确定的2.不同的类型,甚至你自己定义的class,都有不同的"相等"的含义,比如定义user的类,只需id一样。在java 中,判断对象相等需要重写equals和hashCode方法,equals返回true就是相等了,现在连类都未知,怎么去实现它的equals方法呢?ps:感觉实际开发中这种包罗万象的数组存在的可能性微乎其微,可以参考下lodash的unionWith 函数_.unionWith([arrays], [comparator])var&nbsp;objects&nbsp;=&nbsp;[{&nbsp;'x':&nbsp;1,&nbsp;'y':&nbsp;2&nbsp;},&nbsp;{&nbsp;'x':&nbsp;2,&nbsp;'y':&nbsp;1&nbsp;}]; var&nbsp;others&nbsp;=&nbsp;[{&nbsp;'x':&nbsp;1,&nbsp;'y':&nbsp;1&nbsp;},&nbsp;{&nbsp;'x':&nbsp;1,&nbsp;'y':&nbsp;2&nbsp;}];&nbsp; _.unionWith(objects,&nbsp;others,&nbsp;_.isEqual);//&nbsp;=>&nbsp;[{&nbsp;'x':&nbsp;1,&nbsp;'y':&nbsp;2&nbsp;},&nbsp;{&nbsp;'x':&nbsp;2,&nbsp;'y':&nbsp;1&nbsp;},&nbsp;{&nbsp;'x':&nbsp;1,&nbsp;'y':&nbsp;1&nbsp;}]把判断是否相等的代码comparator作为参数,如果有多种类型,就在comparator里面加个类型判断就好了。

繁星淼淼

这个可以看一下&nbsp;lodash&nbsp;的&nbsp;baseUniq&nbsp;源码有&nbsp;array , iteratee, comparator, 数组,迭代器,比较器3个参数function&nbsp;baseUniq(array,&nbsp;iteratee,&nbsp;comparator)&nbsp;{...}这一个方法演化了&nbsp;union, uniq, unionBy, uniqBy, unionWith, uniqWith&nbsp;6个方法如果我们比较&nbsp;[ { age: 1 }, { age: 1 } ]&nbsp;是否重复可以 使用&nbsp;iteratee:item => item.age如果我们比较&nbsp;[ { 'x': 1, 'y': 2 }, { 'x': 1, 'y': 2 } ]&nbsp;是否重复可以 使用&nbsp;comparator:(target, value) => target.x === value.x && target.y === value.y(也可以用其他的方法,遍历,JSON.stringify)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript