利用 hash 去掉 JS array 中重复的 Object

2015-07-05 22:07:03 +08:00
 tedd

通过如下小脚本我希望是去掉JS array中重复的Object,但每次将元素放进hash的时候,key都变成了 '[object Object]',最终导致没有拿到预期的输出,思路应该没有问题,改怎么解决呢?请大人指点一二,谢谢先!

a = [ { a: 'A' }, { b: 'B' }, { a: 'A' } ];
console.log(a);

var hash = {};
for (var i = 0, len = a.length; i < len; i ++) {
  var elem = a[i];
  hash[elem] = elem;
}

var noDuplicate = [], j = 0;
for (var item in hash) {
  noDuplicate[j++] = hash[item];
}

console.log(hash); // { '[object Object]': { a: 'A' } }
console.log(noDuplicate); // [ { a: 'A' } ]

// expected: [ { a: 'A' }, { b: 'B' } ]

p.s. 为什么要支持markdown格式只能发帖后在编辑中才能选择...

3300 次点击
所在节点    JavaScript
5 条回复
Vladimir
2015-07-05 22:15:33 +08:00
第一个for循环中的一次操作是:
var elem = a[0]; //{a:'A'}
hash[{a:'A'}] = {a:'A'}
yangg
2015-07-05 22:39:20 +08:00
对象的.toString() 返回就是 [object Object]了,你想获取对象字符串就用 JSON.stringify() 吧
Huang77
2015-07-05 22:42:04 +08:00
hash[elem] = elem换成hash[JSON.stringify(elem)] = elem
不过应该有更好的方法吧
tedd
2015-07-05 22:46:45 +08:00
@yangg
@Huang77
果然两位的方法有效!感谢!
hbkdsm
2015-07-08 04:39:32 +08:00
1. 考虑 JSON.stringify
```
var a = [ { a: 'A' }, { b: 'B' }, { a: 'A' } ]

// obj --> str --> filtered str --> obj
var noDuplicate = a
.map(function(obj) {
return JSON.stringify(obj)
})
.filter(function(str, idx, a) {
return idx === a.indexOf(str)
})
.map(function(str) {
return JSON.parse(str)
})
```

2. 使用 lodash 的 _.isEqual() 方法
```
var a = [ { a: 'A' }, { b: 'B' }, { a: 'A' } ]
var noDuplicate = a.reduce(function(arr, obj) {
if (arr.some(function(chosen) {
return _.isEqual(chosen, obj)
})) return arr
arr.push(obj)
return arr
}, [])
```

JSON.stringify 不能处理所有对象(循环引用、undefined、method),
_.isEqual 更健壮,不过性能就呵呵了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/203532

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX