isEqual vs isMatch-isMatch是否忽略嵌套数组元素的顺序?

时间:2019-01-23 11:26:00

标签: node.js lodash

我正在使用lodash来比较以下两个对象:

obj1 = {
    "_id": "57767",
    "Re": {
        "PropertyTypes": [
            {
                "AllocationID": 13870,
                "Percentage": null,
                "Type": "Hotels",
                "Value": null
            },
            {
                "AllocationID": 13867,
                "Percentage": null,
                "Type": "Industrial",
                "Value": null
            }
        ]
    }
}

obj2 = {
    "_id": "57767",
    "Re": {
        "PropertyTypes": [
            {
                "AllocationID": 13867,
                "Percentage": null,
                "Type": "Industrial",
                "Value": null
            },
            {
                "AllocationID": 13870,
                "Percentage": null,
                "Type": "Hotels",
                "Value": null
            }
        ]
    }
}

我发现使用isEqual(obj1, obj2)时比较失败,而使用isMatch(obj1, obj2)则比较正常。

我想知道isEqualisMatch是否以完全相同的方式工作,除了{{1}忽略PropertyTypes数组元素的顺序这一事实之外} 在这种情况下。我在isMatch's documentation中找不到此信息。

2 个答案:

答案 0 :(得分:3)

不确定“以完全相同的方式工作”是什么意思,但这是我的理解:

  • _.isMatch_.isEqual共享相同的内部逻辑,_isMatch用显式的 partial unordered 标志调用所述基础逻辑(所以我想我们可以说他们相当的工作方式相同)
  • 我要说一般_isMatch用于声明输入对象-例如一种配置-至少已经[em]至少还没有完全正确地成形,而_.isEqual处理的是最纯粹,最严格的比较
  • 由于这种类似于验证的行为,所以还有部分标记的概念,鉴于您显示的数据,这可能是一个陷阱,例如:
obj1 = {
  a: 123,
  b: 456,
  c: 789
};
obj2 = {
  a: 123,
  b: 456
}
_.isMatch(obj1, obj2); // true, `c` wasn't "asserted"
_.isMatch(obj2, obj1); // false, missing value for `c`

将其扩展为更接近您的案例的例子,因为这是一个深层的比较:

obj1 = {
  PropertyTypes: [{
    id: 13867
  }, {
    id: 13870
  }]
};
obj2 = {
  PropertyTypes: [{
    id: 13867
  }, {
    id: 13870
  }, {
    id: 11111
  }]
};
_.isMatch(obj1, obj2); // false, missing 11111 value
_.isMatch(obj2, obj1); // true, even though there's one more item in the array

希望这会有所帮助!

答案 1 :(得分:1)

它们实际上并非以相同的方式工作,_。isMatch仅执行 partial 深度比较,而_.isEqual执行 full 深度比较。

因此,对于两个简单对象的示例,我们得到以下结果,因为它们重叠,所以isMatch返回true。

在您的情况下,obj1和obj2的“ Re”属性不必完全匹配即可使_.isMatch返回true。

let obj1 = {
    "_id": "57767",
    "Re": {
        "PropertyTypes": [
            {
                "AllocationID": 13870,
                "Percentage": null,
                "Type": "Hotels",
                "Value": null
            },
            {
                "AllocationID": 13867,
                "Percentage": null,
                "Type": "Industrial",
                "Value": null
            }
        ]
    }
}

// Remove Re property of obj2 to demonstrate.
let obj2 = {
    "_id": "57767",
    "Re": { 
    }
}

console.log("_.isEqual(obj1, obj2)", _.isEqual(obj1, obj2));
console.log("_.isMatch(obj1, obj2)", _.isMatch(obj1, obj2));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>