为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

神不在的星期二 2019-03-15 17:10:40
数组去重,很多时候都会用到,在具体项目中因为场景确定,很容易写出一个简单的去重方法,但大多是否具有针对性,没法适用于各类,一劳永逸。当然此处的场景所说的去重指的是去除内容大致相同的数据,不管是否同一个引用。如下这段代码,如果希望输出的是 [[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());通常我们利用Set和Array互转实现去重,但是该方式在判断引用类型时,并没那么给力,只有相同的引用才会被判定为相等。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、function等Object类型的等值判断没有json数据或字符串那般简单。
查看完整描述

2 回答

?
莫回无

TA贡献1865条经验 获得超7个赞

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

var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; 
_.unionWith(objects, others, _.isEqual);// => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]

把判断是否相等的代码comparator作为参数,如果有多种类型,就在comparator里面加个类型判断就好了。


查看完整回答
反对 回复 2019-03-15
?
繁星淼淼

TA贡献1775条经验 获得超11个赞

这个可以看一下 lodash 的 baseUniq 源码
有 array , iteratee, comparator, 数组,迭代器,比较器3个参数

function baseUniq(array, iteratee, comparator) {...}

这一个方法演化了 union, uniq, unionBy, uniqBy, unionWith, uniqWith 6个方法

如果我们比较 [ { age: 1 }, { age: 1 } ] 是否重复可以 使用 iterateeitem => item.age
如果我们比较 [ { 'x': 1, 'y': 2 }, { 'x': 1, 'y': 2 } ] 是否重复可以 使用 comparator(target, value) => target.x === value.x && target.y === value.y(也可以用其他的方法,遍历,JSON.stringify)


查看完整回答
反对 回复 2019-03-15
  • 2 回答
  • 0 关注
  • 553 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信