如何不考虑顺序而检查两个对象数组是否不同?

时间:2018-06-22 04:28:55

标签: javascript arrays lodash javascript-objects

案例1

let x =[{_id:"1",name:"abc"},{_id:"2",name:"def"}]
let y=[{_id:"1",name:"abc"},{_id:"3",name:"def"}]

isDifferent(x,y)必须返回true。

案例2

let a=[{_id:"1",name:"abc"},{_id:"2",name:"def"}]
let b=[{_id:"2",name:"def"},{_id:"1",name:"abc"}]

isDifferent(a,b)必须返回false。

案例3

let p=[{_id:"1",name:"abc"},{_id:"2",name:"def"}]
let q=[{_id:"1",name:"abc"},{_id:"2",name:"def"}]

isDifferent(a,b)必须返回false。

我尝试使用lodash的isMatch函数

 isDifferent(arr1, arr2) {
        return !isMatch(arr1, arr2);
    }

案例1 案例3 可以正常工作。但是在情况2 中,该函数返回true。请注意,只有数组中对象的顺序可以互换。

我无法基于_id进行检查,因为我比较的两个数组可能根本没有_id。

let p=[{name:"abc",age:"2"},{name:"def",age:"2"}]
let q=[{name:"abc",age:"3"},{name:"def",age:"4"}]

数组可能像这样。但是我可以保证的是,两个数组中的对象将具有相同的属性

4 个答案:

答案 0 :(得分:1)

使用lodash提供的isEuqual方法,因为它会在两个值之间进行深入比较以确定它们是否等效。

_.isEqual(array1, array2);

此方法支持比较数组,数组缓冲区,布尔值,日期对象,错误对象,映射,数字,对象对象,正则表达式,集合,字符串,符号和类型化数组。对象对象通过它们自己的(而不是继承的)可枚举属性进行比较。函数和DOM节点通过严格相等的方式进行比较,即===。

答案 1 :(得分:0)

我将使用isEqual()方法。

// False
    let x =[{_id:"1",name:"abc"},{_id:"2",name:"def"}]
    let y= [{_id:"1",name:"abc"},{_id:"3",name:"def"}]

    // true
    let a=[{_id:"1",name:"abc"},{_id:"2",name:"def"}]
    let b=[{_id:"2",name:"def"},{_id:"1",name:"abc"}]

    //true
    let p=[{_id:"1",name:"abc"},{_id:"2",name:"def"}]
    let q=[{_id:"1",name:"abc"},{_id:"2",name:"def"}]

    function compare(a, b) {
    var key = Object.keys(a)[0];
    if (a[key] < b[key])
        return -1;
    if (a[key] > b[key])
        return 1;
    return 0;
}

function sortObject(o) {
    var sorted = {},
        key, a = [];
    for (key in o) {
        if (o.hasOwnProperty(key)) {
            a.push(key);
        }
    }
    a.sort();
    for (key = 0; key < a.length; key++) {
        sorted[a[key]] = o[a[key]];
    }
    return sorted;
}

function isEqual(array1, array2) {
    array1 = array1.map(x => sortObject(x)).sort(compare);
    array2 = array2.map(x => sortObject(x)).sort(compare);
    if (JSON.stringify(array1) === JSON.stringify(array2))
        return true;
    else return false;
}

console.log('Are x and y equal ==> ' + isEqual(x, y));
console.log('Are a and b equal ==> ' + isEqual(a, b));
console.log('Are p and q equal ==> ' + isEqual(p, q));

答案 2 :(得分:0)

您可以将lodash#xorWithlodash#isEqual用作比较器函数,以获取与参数ab不同的项数组。根据结果​​数组的长度,我们可以推断出ab是不同的。

function isDifferent(a, b) {
  return _.xorWith(a, b, _.isEqual).length > 0;
}

let x =[{_id:"1",name:"abc"},{_id:"2",name:"def"}]
let y=[{_id:"1",name:"abc"},{_id:"3",name:"def"}];

let a=[{_id:"1",name:"abc"},{_id:"2",name:"def"}];
let b=[{_id:"2",name:"def"},{_id:"1",name:"abc"}];

let p=[{_id:"1",name:"abc"},{_id:"2",name:"def"}];
let q=[{_id:"1",name:"abc"},{_id:"2",name:"def"}];

console.log(isDifferent(x, y));

console.log(isDifferent(a, b));

console.log(isDifferent(p, q));

function isDifferent(a, b) {
  return _.xorWith(a, b, _.isEqual).length > 0;
}
.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>

答案 3 :(得分:0)

有趣的问题。这是一种解决方案,其工作方式是对数组进行排序,然后使用!_.isEqual进行比较:

let x=[{_id:"1",name:"abc"},{_id:"2",name:"def"}]
let y=[{_id:"1",name:"abc"},{_id:"3",name:"def"}]

let a=[{_id:"1",name:"abc"},{_id:"2",name:"def"}]
let b=[{_id:"2",name:"def"},{_id:"1",name:"abc"}]

let p=[{_id:"1",name:"abc"},{_id:"2",name:"def"}]
let q=[{_id:"1",name:"abc"},{_id:"2",name:"def"}]


const isDifferent = (a, b) => {
  const sortArray = (arr) => _.sortBy(arr, ['id', 'name'])
  return !_.isEqual(sortArray(a), sortArray(b))
}

console.log('x & y: ', isDifferent(x,y))
console.log('a & b: ', isDifferent(a,b))
console.log('p & q: ', isDifferent(p,q))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>