与lodash深度比较的对象数组

时间:2016-05-06 06:24:11

标签: javascript arrays javascript-objects lodash

我有2个对象数组,我与lodash

进行了深入比较

但是,我有一个问题:

> 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 } ]

如何比较两者是否相等?

3 个答案:

答案 0 :(得分:25)

您可以将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(''));
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.11.2/lodash.js"></script>
&#13;
&#13;
&#13;

更新2018年6月22日

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

  

@ryeballar如果任何数组未定义,则返回true。怎么会   你解决了这个问题在此提前感谢好友

differenceWith文档中所述:

  

结果值的顺序和引用由第一个确定   阵列。

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

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

&#13;
&#13;
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);
&#13;
.as-console-wrapper{min-height:100%;top:0}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
&#13;
&#13;
&#13;

答案 1 :(得分:2)

我更喜欢纯粹的JS,因为我没有耐心学习下划线或lodash。所以我发明了我一直梦寐以求的东西。 import { Injectable, OnInit } from '@angular/core' import { FACEBOOK_APPID } from '../constants' @Injectable() export class fbService implements OnInit{ constructor(){} ngOnInit(){ if (!window.fbAsyncInit) { window.fbAsyncInit = function () { FB.init({ appId: FACEBOOK_APPID, xfbml: false, version: 'v2.6' }); FB.api("/me",null,()=>{}) console.log(FB) }; } this.initFB() } initFB(){ var js, id = 'facebook-jssdk', ref = document.getElementsByTagName('script')[0]; if (document.getElementById(id)) { return; } js = document.createElement('script'); js.id = id; js.async = true; js.src = "//connect.facebook.net/en_US/sdk.js"; ref.parentNode.insertBefore(js, ref); } getPost(page:string){ FB.api(`/${page}/feed?limit=1`,null,(response)=>{console.log(response)}) } } 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");

很酷......所以接着我们继续提问......我猜......因为我们已经有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。这也使这项工作更简单。

echo "<script>
    document.addEventListener( 'DOMContentLoaded', function () {
        var picTop = document.getElementById(\"myPic\").offsetTop ;
        var picLeft= document.getElementById(\"myPic\").offsetLeft ;

        document.getElementById(\"" . $iconId. "\").style.top = picTop + " . $iconPosition[$i][0] . " + \"px\"; 
        document.getElementById(\"" . $iconId. "\").style.left = picLeft + " . $iconPosition[$i][1] . " + \"px\"; 
    }, false );
</script>";

答案 2 :(得分:1)

在@ryeballar答案之后,如果您只想导入特定的lodash方法,则可以使用以下表示法:

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


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