在对象上使用唯一的下划线

时间:2014-08-19 14:33:49

标签: javascript underscore.js

我想返回一个唯一的数组,其中房间对象是相同的。

var input = [
  {
    position:{
      room: {
        name: 'WC',
        number: '001'
      }
    }
  },
  {
    position:{
      room: {
        name: 'WC',
        number: '001'
      }
    }
  },
  {
    position:{
      room: {
        name: 'RWC',
        number: '007'
      }
    }
  }
];

所以这个列表将是:

var input = [
  {
    position:{
      room: {
        name: 'WC',
        number: '001'
      }
    }
  },
  {
    position:{
      room: {
        name: 'RWC',
        number: '007'
      }
    }
  }
];

我试过了:

  var distinctRooms = _.uniq(input, function(input){
    return input.position.room
  });

但它返回整个列表。没有看到任何比较对象的例子。是否可以使用_uniq进行某种操作?

4 个答案:

答案 0 :(得分:1)

房间对象不同。如果你根据他们的号码认为房间相等,你可以使用

  var distinctRooms = _.uniq(input, function(input){
    return input.position.room.number;
  });

答案 1 :(得分:0)

也许你应该看一下这个answer迭代的地方并创建一个具有唯一值的数组。

答案 2 :(得分:0)

使用提供深层对象比较的_.isEqual() function,可以创建一个将其应用于对象数组并从该函数创建混合的函数。

算法:

  1. 从列表中取出第一个元素( head ),将其存储在结果中
  2. 迭代列表的其余部分( tail ),删除.isEqual到第一个元素的每个元素
  3. 如果列表的其余部分不为空,则将其传递给步骤1,否则返回结果
  4. 使用递归方法实现的代码:

    _.mixin({
        deepUniq: (function () {
            var dedup = function (coll, result) {
                var head = _.first(coll),
                    tail = _.reject(_.rest(coll), function (curr) {
                        return _.isEqual(curr, head);
                    });
    
                result.push(head);
                return (tail.length) ? dedup(tail, result) : result;
            };
            return function (coll) {
                return dedup(coll, []);
            };
        })()
    });
    

    警告:这种方法具有指数运行时间,即对于长嵌套对象的长列表,它将变得越来越慢。我的建议是比较不同解决方案的正确性和性能。


    免责声明:此解决方案基于https://stackoverflow.com/a/19641747/

答案 3 :(得分:-1)

只要您没有圆形结构,就可以使用JSON Stringify对每个房间属性进行深入比较

_.uniq(input, function(input){
    return JSON.stringify(input.position.room)
  });