【问题标题】:Difference between objects in array数组中对象之间的差异
【发布时间】:2016-11-19 00:06:00
【问题描述】:

我试图找出复杂数组中元素之间的差异。

我的数组列表如下:

[
    [{
        id: 123,
        list: [{
            name: "Vimal",
            status: "Pass"
        }, {
            name: "Selvam",
            status: "Pass"
        }]
    }],
    [{
        id: 124,
        list: [{
            name: "Vimal",
            status: "Pass"
        }, {
            name: "Selvam",
            status: "Fail"
        }, {
            name: "Raj",
            status: "Pass"
        }]
    }]
]

我想得到list之间的区别如下:

[{
    id: 123,
    list: [{
        name: "Selvam",
        status: "Pass"
    }]
}, {
    id: 124,
    list: [{
        name: "Selvam",
        status: "Fail"
    }, {
        name: "Raj",
        status: "Pass"
    }]
}]

我正在考虑循环每个元素并与相邻元素进行比较,然后将差异存储到临时变量中。但这听起来太麻烦了。我只是想请你对我如何改变我看待这个问题的方式提出意见。指针会更有帮助。否则,有没有什么库可以轻松解决这个问题?

编辑1: 请注意,列表的长度始终不是 2。大小是动态的。并且应该在所有元素之间进行比较。

【问题讨论】:

  • 当它们只是乱序时是否标记差异是否重要?
  • @BradBumbalough:没关系
  • 太棒了!您想知道发生了什么 发生了变化,还是只是发生了变化?
  • 所有改变对我来说更有意义
  • 我认为这可能是关于如何处理这个问题的最清晰的解释...stackoverflow.com/questions/7837456/…

标签: javascript reactjs underscore.js


【解决方案1】:

如果您想要差异,则需要两个对象的交集

在您的情况下,您首先需要知道有什么不同。然后您可以使用它来删除属性以了解 对称差异

这是一个非常复杂的问题,因为如果 O(n2) 比较数组。在下面的例子中,我只是比较了 JSON 值。这对您的问题很方便,但不建议用于更复杂的对象数组。

注意:我不知道你为什么选择在没有嵌套数组的情况下将对象包装在数组中?我删除了括号以简化逻辑。查看更改后的 JSON。您可以轻松地将其添加回需要的逻辑中。

var dataArr = getSampleData();
var intersectObj = findObjectIntersection(dataArr[0], dataArr[1], {});

document.body.innerHTML = '<pre>' + JSON.stringify(intersectObj, null, 4) + '</pre>';

// Iterate over all keys and find similar key-values.
function findObjectIntersection(obj1, obj2, obj3) {
  var keys1 = Object.keys(obj1); // Object 1 keys
  var keys2 = Object.keys(obj2); // Object 2 keys
  var keysL = keys1.length > keys2.length ? keys1 : keys2;
  var keysS = keysL === keys1 ? keys2 : keys1;
  var keysD = keysL.filter(function(key) {
    return keysS.indexOf(key) > -1;
  });
  for (var i = 0; i < keysD.length; i++) {
    var currKey = keysD[i];
    var val1 = obj1[currKey];
    var val2 = obj2[currKey];

    if (isValue(val1) && isValue(val2)) {
      if (val1 === val2) {
        obj3[currKey] = val1;
      }
    } else if (isArray(val1) && isArray(val2)) {
      obj3[currKey] = findArrayIntersectionSimple(val1, val2, []);
    }
  }
  return obj3;
}

// Only compare values by JSON.
function findArrayIntersectionSimple(arr1, arr2, arr3) {
  var arrL = arr1.length > arr2.length ? arr1 : arr2;
  var arrS = arrL === arr1 ? arr2 : arr1;
  for (var i = 0; i < arrL.length; i++) {
    for (var j = 0; j < arrS.length; j++) {
      var val1 = JSON.stringify(arrL[i]);
      var val2 = JSON.stringify(arrS[j]);
      if (val1 === val2) {
        arr3.push(arrL[i]);
      }
    }
  }
  return arr3;
}

function isFunction(obj) {
  return {}.toString.apply(obj) === '[object Function]';
}

function isArray(obj) {
  return {}.toString.apply(obj) === '[object Array]';
}

function isObject(obj) {
  return {}.toString.apply(obj) === '[object Object]';
}

function isValue(obj) {
  return !isObject(obj) && !isArray(obj);
}

function getSampleData() {
  return [{
    id: 123,
    list: [{
      name: "Vimal",
      status: "Pass"
    }, {
      name: "Selvam",
      status: "Pass"
    }]
  }, {
    id: 124,
    list: [{
      name: "Vimal",
      status: "Pass"
    }, {
      name: "Selvam",
      status: "Fail"
    }, {
      name: "Raj",
      status: "Pass"
    }]
  }];
}

【讨论】:

  • 我想我没有正确沟通。您假设列表的长度始终为 2。但在我的情况下,长度将是动态的。
【解决方案2】:

正如Mr. Polywhirl 所说,您想获得两个数组之间的对称差。

碰巧,Lodash 有一个实用函数:xorWith

这是一个用法示例:

var symmetricDifference = _.xorWith(array1, array2, comparisonFn);

在本例中,xorWith() 使用 comparisonFn 函数比较 array1array2 的值。

由于数组的值是对象,因此您需要使用比较函数来深入检查对象是否相等。 Lodash 正好有这样一个比较功能:isEqual

因此,对于您的用例,您可能会通过以下代码获得两个列表之间的对称差异(我们称它们为 list1list2):

var symmetricDifference = _.xorWith(list1, list2, _.isEqual);

【讨论】:

  • 我对我的问题进行了编辑。我不想比较两个数组,我想在元素之间进行比较。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-07
  • 2019-12-05
  • 2019-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多