Javascript 对象数组与 lodash 的深度比较

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37065663/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 19:50:44  来源:igfitidea点击:

Array of object deep comparison with lodash

javascriptarraysjavascript-objectslodash

提问by Archer

I've 2 array of objects that I'd deeply compare with lodash

我有 2 个对象数组,我将与之进行深入比较 lodash

However, I've a prob with it:

但是,我有一个问题:

> var x = [{a:1, b:2}, {c:3, d:4}];
> var y = [{b:2, a:1}, {d:4, c:3}];
> _.difference(x,y, _.isEqual);
[ { a: 1, b: 2 }, { c: 3, d: 4 } ]

How should I compare to see that both are equal?

我应该如何比较才能看到两者相等?

回答by ryeballar

You can make use of differenceWith()with an isEqual()comparator, and invoke isEmptyto check if they are equal or not.

您可以将differenceWith()isEqual()比较器一起使用,并调用isEmpty来检查它们是否相等。

var isArrayEqual = function(x, y) {
  return _(x).differenceWith(y, _.isEqual).isEmpty();
};

var result1 = isArrayEqual(
  [{a:1, b:2}, {c:3, d:4}],
  [{b:2, a:1}, {d:4, c:3}]
);

var result2 = isArrayEqual(
  [{a:1, b:2, c: 1}, {c:3, d:4}],
  [{b:2, a:1}, {d:4, c:3}]
);

document.write([
  '<div><label>result1: ', result1, '</label></div>',
  '<div><label>result2: ', result2, '</label></div>',
].join(''));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.11.2/lodash.js"></script>

UPDATE June 22, 2018

2018 年 6 月 22 日更新

This update is in response to the comment below:

此更新是对以下评论的回应:

@ryeballar if any of the array is undefined it returns true. How would you solve this. Thanks in advance buddy

@ryeballar 如果任何数组未定义,则返回 true。你会如何解决这个问题。预先感谢朋友

As stated in the differenceWithdocumentation:

differenceWith文档中所述:

The order and references of result values are determined by the first array.

结果值的顺序和引用由第一个数组决定。

This means that as long as all the items in the first array will match everything else in the second array, then the resulting array from the differenceWithinvocation will be empty.

这意味着只要第一个数组中的所有项都匹配第二个数组中的所有其他项,那么differenceWith调用的结果数组将为空。

An alternative solution that truly solves the problem is to use xorWith()with the same chain of functions from the solution above.

真正解决问题的另一种解决方案是使用xorWith()与上述解决方案相同的功能链。

var isArrayEqual = function(x, y) {
  return _(x).xorWith(y, _.isEqual).isEmpty();
};

var result1 = isArrayEqual(
  [{a:1, b:2}, {c:3, d:4}],
  [{b:2, a:1}, {d:4, c:3}]
);

var result2 = isArrayEqual(
  [{a:1, b:2, c: 1}, {c:3, d:4}],
  [{b:2, a:1}, {d:4, c:3}]
);

var result3 = isArrayEqual(
  [{a:1, b:2, c: 1}, {c:3, d:4}],
  [{b:2, a:1}, {d:4, c:3}, undefined]
);

console.log('result1:', result1);
console.log('result2:', result2);
console.log('result3:', result3);
.as-console-wrapper{min-height:100%;top:0}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>

回答by Anita

Following @ryeballar answer, if you only want to import specific lodash methods you can use this notation:

按照@ryeballar 的回答,如果您只想导入特定的 lodash 方法,您可以使用此表示法:

import { isEmpty, isEqual, xorWith } from 'lodash';


export const isArrayEqual = (x, y) => isEmpty(xorWith(x, y, isEqual));

回答by Redu

I prefer pure JS since i haven't got the patience to learn underscore or lodash. So i invent something i have been long dreaming of. The Object.prototype.compare(). The v0.0.2 is doing only shallow comparison though but adequate for this question.

我更喜欢纯 JS,因为我没有耐心学习下划线或 lodash。所以我发明了我一直梦想的东西。的Object.prototype.compare()。v0.0.2 只做浅层比较,但足以解决这个问题。

Object.prototype.compare = function(o){
  var ok = Object.keys(this);
  return typeof o === "object" && ok.length === Object.keys(o).length ? ok.every(k => this[k] === o[k]) : false;
};
var obj1 = {a:1,b:2,c:3},
    obj2 = {c:3,a:1,b:2},
    obj3 = {b:2,c:3,a:7};

document.write ("<pre>" + obj1.compare(obj2) + "</pre>\n");
document.write ("<pre>" + obj2.compare(obj3) + "</pre>\n");
document.write ("<pre>" + new Object({a:1, b:2, c:3}).compare({c:3,b:2,a:1,d:0}) + "</pre>\n");

Cool... So then lets continue with the question... I guess... since we already have an Object.prototype.compare()there should be absolutely no harm in the invention of Array.prototype.compare(). Lets make it more clever this time. It shall tell primitives from objects. One other thing is, arrays are ordered; so in my book [1,2]is not equal to [2,1]. Also this makes the job simpler.

酷......所以后来让我们继续用这个问题......我想......因为我们已经有一个Object.prototype.compare()应该有绝对的发明中,没有坏处Array.prototype.compare()。这次让我们让它更聪明。它应该从对象中分辨出原语。另一件事是,数组是有序的;所以在我的书中[1,2]不等于[2,1]. 这也使工作更简单。

Object.prototype.compare = function(o){
  var ok = Object.keys(this);
  return typeof o === "object" && ok.length === Object.keys(o).length ? ok.every(k => this[k] === o[k]) : false;
};
Array.prototype.compare = function(a){
  return this.every((e,i) => typeof a[i] === "object" ? a[i].compare(e) : a[i] === e);
}
var x = [{a:1, b:2}, {c:3, d:4}],
    y = [{b:2, a:1}, {d:4, c:3}],
    a = [1,2,3,4,5],
    b = [1,2,3,4,5],
    p = "fourtytwo",
    r = "thirtyseven",
    n = 42,
    m = 37;
document.writeln(x.compare(y)); // the question is answered here
document.writeln(a.compare(b));
document.writeln(p.compare(r)); // these primitives end up at Object prototype
document.writeln(n.compare(m)); // so modify Object.prototype.compare () accordingly