V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
tedd
V2EX  ›  JavaScript

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

  •  
  •   tedd · 2015-07-05 22:07:03 +08:00 · 3214 次点击
    这是一个创建于 3217 天前的主题,其中的信息可能已经有所发展或是发生改变。

    通过如下小脚本我希望是去掉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格式只能发帖后在编辑中才能选择...

    5 条回复    2015-07-08 04:39:32 +08:00
    Vladimir
        1
    Vladimir  
       2015-07-05 22:15:33 +08:00
    第一个for循环中的一次操作是:
    var elem = a[0]; //{a:'A'}
    hash[{a:'A'}] = {a:'A'}
    yangg
        2
    yangg  
       2015-07-05 22:39:20 +08:00   ❤️ 1
    对象的.toString() 返回就是 [object Object]了,你想获取对象字符串就用 JSON.stringify() 吧
    Huang77
        3
    Huang77  
       2015-07-05 22:42:04 +08:00   ❤️ 1
    hash[elem] = elem换成hash[JSON.stringify(elem)] = elem
    不过应该有更好的方法吧
    tedd
        4
    tedd  
    OP
       2015-07-05 22:46:45 +08:00
    @yangg
    @Huang77
    果然两位的方法有效!感谢!
    hbkdsm
        5
    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 更健壮,不过性能就呵呵了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1263 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 18:08 · PVG 02:08 · LAX 11:08 · JFK 14:08
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.