I have the following two arrays:
JavaScript
x
3
1
var oldOrder = [{"Id": "10","Qty": 1}, {"Id": "3","Qty": 2}, {"Id": "9","Qty": 2}];
2
var newOrder = [{"Id": "5","Qty": 2},{"Id": "10","Qty": 3}, {"Id": "9","Qty": 1}];
3
I need to end up with a newArray containing only one object per Id, but if the ids in an object in the oldOrder array and newOrder array then I need to get the difference in the Qty positive or negative. So for example the above would create this new array:
JavaScript
1
2
1
var newArray = [{"Id": "5","Qty": 2},{"Id": "10","Qty": 2}, {"Id": "9","Qty": -1}];
2
I would also like to get the dropped orders that are present in the oldOrder Array but not in the newOrder array:
JavaScript
1
2
1
var droppedOrders = [{"Id": "3","Qty": 2}];
2
I have already got this logic for getting the dropped orders but I am struggling with creating the newArray and tying the logic into the same function if possible?
JavaScript
1
12
12
1
function comparer(otherArray){
2
return function(current){
3
var onlyInOld = otherArray.filter(function(other){
4
return other.Id == current.Id;
5
}).length == 0;
6
return onlyInOld;
7
}
8
}
9
10
var droppedOrders= oldOrder.filter(comparer(newOrder));
11
console.log(droppedOrders);
12
Edited to add that I cannot use ESC6 features like spread or fat arrow etc.
Advertisement
Answer
You can easily achieve the result using Map
1) Using ES6
JavaScript
1
22
22
1
var oldOrder = [
2
{ Id: "10", Qty: 1 },
3
{ Id: "3", Qty: 2 },
4
{ Id: "9", Qty: 2 },
5
];
6
var newOrder = [
7
{ Id: "5", Qty: 2 },
8
{ Id: "10", Qty: 3 },
9
{ Id: "9", Qty: 1 },
10
];
11
12
const oldMap = new Map(oldOrder.map((o) => [o.Id, o]));
13
const newMap = new Map(newOrder.map((o) => [o.Id, o]));
14
15
const result = newOrder.map((o) =>
16
oldMap.has(o.Id) ? { o, Qty: o.Qty - oldMap.get(o.Id).Qty } : o
17
);
18
19
const droppedOrders = oldOrder.filter(({ Id }) => !newMap.has(Id));
20
21
console.log(result);
22
console.log(droppedOrders);
JavaScript
1
6
1
/* This is not a part of answer. It is just to give the output fill height. So IGNORE IT */
2
3
.as-console-wrapper {
4
max-height: 100% !important;
5
top: 0;
6
}
2) Using ES5
JavaScript
1
32
32
1
var oldOrder = [
2
{ Id: "10", Qty: 1 },
3
{ Id: "3", Qty: 2 },
4
{ Id: "9", Qty: 2 },
5
];
6
var newOrder = [
7
{ Id: "5", Qty: 2 },
8
{ Id: "10", Qty: 3 },
9
{ Id: "9", Qty: 1 },
10
];
11
12
const oldMap = {};
13
const newMap = {};
14
oldOrder.forEach(function (o) {
15
oldMap[o.Id] = o;
16
});
17
newOrder.forEach(function (o) {
18
newMap[o.Id] = o;
19
});
20
21
const result = newOrder.map(function (o) {
22
return oldMap[o.Id]
23
? Object.assign({}, o, { Qty: o.Qty - oldMap[o.Id].Qty })
24
: o;
25
});
26
27
const droppedOrders = oldOrder.filter(function (o) {
28
return !newMap[o.Id];
29
});
30
31
console.log(result);
32
console.log(droppedOrders);
JavaScript
1
2
1
/* This is not a part of answer. It is just to give the output fill height. So IGNORE IT */
2
.as-console-wrapper { max-height: 100% !important; top: 0; }