比较javascript中的2个数组并提取差异

时间:2017-05-02 18:38:38

标签: javascript arrays

数组1是来自localstorage

的数据的结果

对于相同的ID(329,307,355),数组2是治疗后的结果

所以我需要比较两者以通知改变了什么

数组1:

[{"329":["45738","45737","45736"]},{"307":["45467","45468"]},{"355":["47921"]}]

数组2:

[{"355":["47921","45922"]},{"329":["45738","45737","45736"]},{"307":[]}]

我需要将数组2与数组1进行比较并提取差异。

在这个例子中,我希望获得结果

[{"355":["45922"]},{"307":[]}]

我尝试调整此代码:

var compareJSON = function(obj1, obj2) {
  var ret = {};
  for(var i in obj2) {
    if(!obj1.hasOwnProperty(i) || obj2[i] !== obj1[i]) {
      ret[i] = obj2[i];
    }
  }
  return ret;
};

可运行:

var array1 = [{
    "329": ["45738", "45737", "45736"]
  }, {
    "307": ["45467", "45468"]
  }, {
    "355": ["47921"]
  }],
  array2 = [{
    "355": ["47921", "45922"]
  }, {
    "329": ["45738", "45737", "45736"]
  }, {
    "307": []
  }]

var compareJSON = function(obj1, obj2) {
  var ret = {};
  for (var i in obj2) {
    if (!obj1.hasOwnProperty(i) || obj2[i] !== obj1[i]) {
      ret[i] = obj2[i];
    }
  }
  return ret;
};

console.log(compareJSON(array1, array2));

但是,要么我什么都没有,要么我有整张桌子

3 个答案:

答案 0 :(得分:1)

您的要求(结果)不明确,但这会让您开始。



var arr1 = [{ "329": ["45738", "45737", "45736"] }, { "307": ["45467", "45468"] }, { "355": ["47921"] }],
  arr2 = [{ "355": ["47921", "45922"] }, { "329": ["45738", "45737", "45736"] }, { "307": [] }];

var result = [];

arr2.forEach(obj => {
  var key = Object.keys(obj)[0];
  var match = arr1.find(o => o.hasOwnProperty(key));
  if (match) {
    var newObj = {};
    newObj[key] = obj[key].filter(s => match[key].indexOf(s) === -1);
    if (!obj[key].length || newObj[key].length) result.push(newObj)
  } else {
    result.push(Object.assign({}, obj));
  }
});

console.log(result);




答案 1 :(得分:0)

您可以使用哈希tbale并删除找到的项目。如果某些项目仍然存在,则会将一个空数组带到结果对象。



var array1 = [{ 329: ["45738", "45737", "45736"] }, { 307: ["45467", "45468"] }, { 355: ["47921"] }],
    array2 = [{ 355: ["47921", "45922"] }, { 329: ["45738", "45737", "45736"] }, { 307: [] }],
    hash = {},
    result = [];

array1.forEach(function (o) {
    Object.keys(o).forEach(function (k) {
        hash[k] = hash[k] || {};
        o[k].forEach(function (a) {
            hash[k][a] = true;
        });
    });
});

array2.forEach(function (o) {
    var tempObject = {};
    Object.keys(o).forEach(function (k) {
        var tempArray = [];
        o[k].forEach(function (a) {
            if (hash[k][a]) {
                delete hash[k][a];
            } else {
                tempArray.push(a);
            }
        });
        if (tempArray.length || Object.keys(hash[k]).length) {
            tempObject[k] = tempArray;
        }
    });
    Object.keys(tempObject).length && result.push(tempObject);
});

console.log(result);




答案 2 :(得分:0)

我之前在npm中使用了deep-diff package来处理这类事情:

它可能比你想要的更详细 - 这里是输出格式自述文件的一个例子:

[ { kind: 'E',
  path: [ 'name' ],
  lhs: 'my object',
  rhs: 'updated object' },
{ kind: 'E',
  path: [ 'details', 'with', 2 ],
    lhs: 'elements',
    rhs: 'more' },
{ kind: 'A',
  path: [ 'details', 'with' ],
  index: 3,
  item: { kind: 'N', rhs: 'elements' } },
{ kind: 'A',
  path: [ 'details', 'with' ],
  index: 4,
  item: { kind: 'N', rhs: { than: 'before' } } } ]

查看上面链接的github页面上的自述文件,了解其含义的详细信息,或try it out for yourself online using runkit

但为了实现这一点,您必须进行某种预处理:

根据每个元素的第一个键对数组进行排序:

a1 = a1.sort((lhs, rhs) => {
  return parseInt(Object.keys(lhs)[0]) - parseInt(Object.keys(rhs)[0]);
})

如果您按每个元素的第一个键对两个数组进行排序,然后将其传递给diff工具,则会得到以下结果:

[
  {"kind":"A","path":[0,"307"],"index":0,"item":{"kind":"D","lhs":"45467"}},
  {"kind":"A","path":[0,"307"],"index":1,"item":{"kind":"D","lhs":"45468"}},
  {"kind":"A","path":[2,"355"],"index":1,"item":{"kind":"N","rhs":"45922"}}
]

如果是我,我可能会合并所有数组元素并对结果对象进行区分,这样您就可以完全避免任何对象顺序和重复键问题。

替代方案:将数组内容合并到一个对象

天真合并可能如下所示:

a1Object = {}

a1.forEach((element) => { 
    Object.keys(element).forEach((key) => {
        a1Object[key] = element[key];
    });
})

产生以下差异:

[
  {"kind":"A","path":["307"],"index":0,"item":{"kind":"D","lhs":"45467"}},
  {"kind":"A","path":["307"],"index":1,"item":{"kind":"D","lhs":"45468"}},
  {"kind":"A","path":["355"],"index":1,"item":{"kind":"N","rhs":"45922"}}
]

解释diff输出

  • 指数A的{​​{1}} rray值发生了变化:3070
  • 指数45467的{​​{1}} rray值发生了变化:DA
  • 指数307 1的{​​{1}} rray值发生了变化:45468已添加D