Tengo las siguientes dos matrices:
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}];Necesito terminar con un newArray que contenga solo un objeto por ID, pero si los ID en un objeto en el arreglo oldOrder y el arreglo newOrder, entonces necesito obtener la diferencia en la cantidad positiva o negativa. Entonces, por ejemplo, lo anterior crearía esta nueva matriz:
var newArray = [{"Id": "5","Qty": 2},{"Id": "10","Qty": 2}, {"Id": "9","Qty": -1}];También me gustaría obtener los pedidos eliminados que están presentes en el conjunto de pedidos antiguos pero no en el conjunto de pedidos nuevos:
var droppedOrders = [{"Id": "3","Qty": 2}];Ya tengo esta lógica para obtener los pedidos descartados, pero tengo problemas para crear el newArray y vincular la lógica a la misma función si es posible.
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);Editado para agregar que no puedo usar las funciones de ESC6 como flecha extendida o gruesa, etc.
Puede lograr fácilmente el resultado usando Map
1) Usando 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) Usando 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; }Intente usar Array.map y Array.filter
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 newArray = newOrder.map((node) => { const nodeFromOldArray = oldOrder.find((item) => item.Id === node.Id); if (nodeFromOldArray) { return { Id: node.Id, Qty: nodeFromOldArray.Qty - node.Qty } } else { return node; } }); const droppedOrders = oldOrder.filter((item) => !newArray.find(node => node.Id === item.Id)) console.log(newArray); console.log(droppedOrders);Una forma de lograrlo es tecleando las matrices de orden antiguo y nuevo por Id. Después de ingresar todo lo demás, debería ser tan simple como usar el filtro y el mapa:
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}]; var keyedOldOrder = keyBy(oldOrder, 'Id'); var keyedNewOrder = keyBy(newOrder, 'Id'); var newArray = newOrder.map(function (entity) { var subtract = keyedOldOrder.hasOwnProperty(entity.Id) ? keyedOldOrder[entity.Id].Qty : 0; return Object.assign({}, entity, { Qty: entity.Qty - subtract }); }); var droppedOrders = oldOrder.filter(function (entity) { return !keyedNewOrder.hasOwnProperty(entity.Id); }); console.log(newArray); console.log(droppedOrders); function keyBy(array, field) { return array.reduce(function (carry, entity) { carry[entity[field]] = entity; return carry; }, {}); }