使用underscore.js比较两个对象

22

我正在尝试使用underscore比较两个对象。

对象1(过滤器)

{
  "tuxedoorsuit":"tuxedoorsuit-tuxedo",
  "occasions":"occasions-wedding"
}

对象2 (属性)

{
  "tuxedoorsuit":"tuxedoorsuit-tuxedo",
  "occasions":"occasions-wedding",
  "occasions":"occasions-prom",
  "product_fit":"product_fit-slim",
  "colorfamily":"colorfamily-black"
}

我希望在Object 2中找到Object 1的所有项时返回true。哪个下划线方法最好使用?

7
http://underscorejs.org/#isEqual 和 http://underscorejs.org/#isMatch 这两个函数怎么样? - Arnaldo Ignacio Gaspar Véjar
1
@ArnaldoIgnacioGasparVéjar:你应该将它做为答案。这比当前被接受的更好。 - Bergi
@Bergi:我同意isMatch会更好。但实际上有趣的是,它在这种情况下不起作用,因为“Object 2”格式不正确。它有两次相同的属性occasionsisMatch将“Object 2”转换为标准对象,这只会保留此属性的最后一个值:occasions-prom。然后它将返回false - slaur4
@ArnaldoIgnacioGasparVéjar 哦,不错 :) 我在我的答案中包含了 isMatch。谢谢 :) - thefourtheye
实际上,对象语法格式不正确导致解析器删除“第一个”值(或在严格模式下引发语法错误)。 isMatch 在这里没有责任,任何其他方法都会产生相同的结果 - 除非它将对象2作为JSON并在内部使用宽容的解析器。 - Bergi
3个回答

36

编辑: 根据Arnaldo的评论,您可以使用isMatch函数,像这样

console.log(_.isMatch(object2, object1));

描述如下:

_.isMatch(object, properties)

告诉你properties中的键和值是否都包含在object中。

如果您想自己进行迭代,只需使用_.keys_.every,像这样:

_.every(_.keys(object1), function(currentKey) {
    return _.has(object2, currentKey) &&
        _.isEqual(object1[currentKey], object2[currentKey]);
});

或者是链接版本,

var result = _.chain(object1)
    .keys()
    .every(function(currentKey) {
        return _.has(object2, currentKey) &&
            _.isEqual(object1[currentKey], object2[currentKey]);
    })
    .value();
如果结果为true,则表示 object1 中的所有键都在object2中,并且它们的值也相等。这基本上遍历了object1的所有键,并检查与object1中的键对应的值是否等于object2中的值。

我该如何在 _.filter 中使用这个? - Casey
@Casey 请编辑问题并包含所有信息。 - thefourtheye
这个很好用!我能够稍微修改一下,让它在 _.filter() 中工作。谢谢! - Casey
实际上,看起来如果找到了object1的第一项,那么它就不会检查第二项。 - Casey
@Casey JavaScript对象是HashMap实现。因此,如果有两个项目映射到相同的哈希值,则其中任何一个都将被另一个覆盖。 - thefourtheye
这段代码的问题在于,如果object2拥有比object1更多的属性,则比较将不会考虑非object1的属性,并且如果它的属性相等,则结果为true。这不是有效的响应。例如: Object1 = {a: 1, b:2}, Object2 = {a: 1, b:2, c:3}object1 === object2 结果:true 期望:false - toskebre

12

使用underscore.js比较两个对象

 **isEqual :** _.isEqual(object, other) 

执行两个对象之间的优化深度比较,以确定它们是否应被视为相等。

示例:

var stooge = {name: 'moe', luckyNumbers: [13, 27, 34]};
    var clone  = {name: 'moe', luckyNumbers: [13, 27, 34]};
     _.isEqual(stooge, clone)  
      Returns True

1
虽然isEqual很有用,但如果其他对象有额外的属性(如OP的情况),它将无法起作用。 - Emile Bergeron
3
如果键的顺序不完全相同,它也无法工作 :/ - zero_cool
@zero_cool 键的顺序不应该有影响。JSON 只会对数组排序,而不是哈希表。 - Akash Agarwal

1
基于之前创建的函数,创建一个简单的控制台输出函数:
var compareMe = function (obj1, obj2, parentKey) {
  parentKey = parentKey || '';
  _.each(_.keys(obj1), function (key) {
    if(_.isObject(obj1[key]) ) {
        compareMe(obj1[key], obj2[key], parentKey + key + '.')
    } else {
        if (!_.has(obj2, key) || !_.isEqual(obj1[key], obj2[key])) {
            console.log(parentKey + key, obj1[key], obj2[key]);
        }
    }
  })
};

并且调用方式为:compareMe(obj1, obj2)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接