首页 > 解决方案 > 比较两个对象数组以匹配属性,然后创建两个新数组

问题描述

我有以下两个数组:

var oldOrder = [{"Id": "10","Qty": 1}, {"Id": "3","Qty": 2}, {"Id": "9","Qty": 2}]; 
var newOrder = [{"Id": "5","Qty": 2},{"Id": "10","Qty": 3}, {"Id": "9","Qty": 1}];

我需要最终得到一个 newArray,每个 Id 只包含一个对象,但是如果 oldOrder 数组和 newOrder 数组中的对象中的 id 则我需要得到 Qty 正数或负数的差异。因此,例如上面将创建这个新数组:

var newArray = [{"Id": "5","Qty": 2},{"Id": "10","Qty": 2}, {"Id": "9","Qty": -1}];

我还想获取 oldOrder 数组中存在但 newOrder 数组中不存在的已删除订​​单:

var droppedOrders = [{"Id": "3","Qty": 2}];

我已经有了这个逻辑来获取丢弃的订单,但是我正在努力创建 newArray 并将逻辑绑定到同一个函数中(如果可能)?

function comparer(otherArray){
  return function(current){
    var onlyInOld = otherArray.filter(function(other){
      return other.Id == current.Id;
    }).length == 0;
    return onlyInOld;
  }
}

var droppedOrders= oldOrder.filter(comparer(newOrder));
console.log(droppedOrders);

编辑添加我不能使用 ESC6 功能,如展开或粗箭头等。

标签: javascriptarraysobject

解决方案


您可以使用Map轻松实现结果

1)使用ES6

var oldOrder = [
  { Id: "10", Qty: 1 },
  { Id: "3", Qty: 2 },
  { Id: "9", Qty: 2 },
];
var newOrder = [
  { Id: "5", Qty: 2 },
  { Id: "10", Qty: 3 },
  { Id: "9", Qty: 1 },
];

const oldMap = new Map(oldOrder.map((o) => [o.Id, o]));
const newMap = new Map(newOrder.map((o) => [o.Id, o]));

const result = newOrder.map((o) =>
  oldMap.has(o.Id) ? { ...o, Qty: o.Qty - oldMap.get(o.Id).Qty } : o
);

const droppedOrders = oldOrder.filter(({ Id }) => !newMap.has(Id));

console.log(result);
console.log(droppedOrders);
/* This is not a part of answer. It is just to give the output fill height. So IGNORE IT */

.as-console-wrapper {
  max-height: 100% !important;
  top: 0;
}

2)使用ES5

var oldOrder = [
  { Id: "10", Qty: 1 },
  { Id: "3", Qty: 2 },
  { Id: "9", Qty: 2 },
];
var newOrder = [
  { Id: "5", Qty: 2 },
  { Id: "10", Qty: 3 },
  { Id: "9", Qty: 1 },
];

const oldMap = {};
const newMap = {};
oldOrder.forEach(function (o) {
  oldMap[o.Id] = o;
});
newOrder.forEach(function (o) {
  newMap[o.Id] = o;
});

const result = newOrder.map(function (o) {
  return oldMap[o.Id]
    ? Object.assign({}, o, { Qty: o.Qty - oldMap[o.Id].Qty })
    : o;
});

const droppedOrders = oldOrder.filter(function (o) {
  return !newMap[o.Id];
});

console.log(result);
console.log(droppedOrders);
/* This is not a part of answer. It is just to give the output fill height. So IGNORE IT */
.as-console-wrapper { max-height: 100% !important; top: 0; }


推荐阅读