Comparing And Adding Items To Array Of Objects
Solution 1:
You could use a hash table for the inventory and check against and update currInv
.
var curInv = [[21, "Bowling Ball"], [2, "Dirty Sock"], [2, "cat"], ],
newInv = [[21, "Bowling Ball"], [2, "Dirty Sock"], [3, "rags"], [3, "mugs"]],
inventory = Object.create(null);
curInv.forEach(function (a) {
this[a[1]] = a;
}, inventory);
newInv.forEach(function (a) {
if (!this[a[1]]) {
this[a[1]] = [0, a[1]];
curInv.push(this[a[1]]);
}
this[a[1]][0] += a[0];
}, inventory);
console.log(curInv);
.as-console-wrapper { max-height: 100%!important; top: 0; }
Solution 2:
You are over-complicating things I think. Here's a working snippet.
functionupdateInventory(arr1, arr2) {
for (var i = 0; i < arr2.length; i++) {
var matchFound = false;
for (var j = 0; j < arr1.length; j++) {
if (arr1[j][1] === arr2[i][1]) {
arr1[j][0] += arr2[i][0];
matchFound = true;
}
}
if (!matchFound) {
arr1.push(arr2[i]);
}
}
return arr1;
}
var curInv = [
[21, "Bowling Ball"],
[2, "Dirty Sock"],
[2, "cat"],
];
var newInv = [
[21, "Bowling Ball"],
[2, "Dirty Sock"],
[3, "rags"],
[3, "mugs"]
];
console.log(updateInventory(curInv, newInv));
What it does
- Loop through all of the elements in
arr2
. - Loop through all of the elements in
arr1
. - If a match is found, add the number of items in
arr2
to the corresponding value inarr1
. - If no match is found, add that element in
arr2
toarr1
.
Solution 3:
You can merge the arrays Or combine the array so it will automatically do what you want .
var array3 = curInv.concat(newInv);
If you want to find the unique elements
// Merges both arrays and gets unique items var array3 = **
arrayUnique(array1.concat(array2));
functionarrayUnique(array) {
var a = array.concat();
for(var i=0; i<a.length; ++i) {
for(var j=i+1; j<a.length; ++j) {
if(a[i] === a[j]) a.splice(j--, 1); }
}
return a;
}
**
Solution 4:
Here is a concise functional programming style solution that uses a hash (a Map
actually) for efficiency:
functionupdatedInventory(a, b) {
returnArray.from(
b.reduce( (m, [v,k]) => m.set(k, (m.get(k) || 0) + v),
newMap(a.map ( ([v,k]) => [k,v] )) ), // swap pairs([k,v]) => [v,k]) // swap back afterwards;
}
// Sample datavar curInv = [
[21, "Bowling Ball"],
[2, "Dirty Sock"],
[2, "cat"],
];
var newInv = [
[21, "Bowling Ball"],
[2, "Dirty Sock"],
[3, "rags"],
[3, "mugs"]
];
// call the function
curInv = updatedInventory(curInv, newInv);
// Output the resultconsole.log(curInv);
.as-console-wrapper { max-height: 100%!important; top: 0; }
If your data would have pairs where the name is in the first element, and the number in the second, the code would have been much shorter. That is because Map
objects are initialised with keys - value pairs, not value - key pairs:
functionupdatedInventory(a, b) {
return [...b.reduce( (m, [v,k]) => m.set(k, (m.get(k) || 0) + v), newMap(a) )];
}
// Sample datavar curInv = [
["Bowling Ball", 21],
["Dirty Sock", 2],
["cat", 2],
];
var newInv = [
["Bowling Ball", 21],
["Dirty Sock", 2],
["rags", 2],
["mugs", 2]
];
// call the function
curInv = updatedInventory(curInv, newInv);
// Output the resultconsole.log(curInv);
.as-console-wrapper { max-height: 100%!important; top: 0; }
Because this function does not mutate the passed arguments, but returns the result, I have called it updatedInventory instead of updateInventory.
Issues with the code you tried with
your outer loop is on the first array, but that is not very practical, as you'll have a difficult time to identify the values that are missing in it. You should really loop over the second array first. Then you will find the elements that are missing in the first array.
There seems no good reason to start the inner loop at the index the outer one is currently at. So you'd better start at 0. Together with the first point, this would make your loops look like this:
for (var j = 0; j < arr2.length; j++) { for (var i = 0; i < arr1.length; i++) {
When finding a match, there is no reason to look further, so you should then exit the inner loop:
if (arr1[i][1] === arr2[j][1]) { arr1[i][0] += arr2[j][0]; break; }
The second
if
you have, is really initiating a third loop, asindexOf
performs an iteration. Furthermore, you are looking inarr1[i]
which only has two elements: a value and a key. That was not your intension, I'm sure.Instead this code should be moved outside of the inner loop, and be corrected to look like this (again, taken into account your loops are swapped according to point 2):
if (i >= arr1.length) { // this indicates no match was found arr1.push(arr2[j]); }
The third
if
was trying to align the length of the array, but it could well add an element that was already present in the other array! So that just has to go. In fact, the previous suggested correction would already make the arrays get aligned.The
break
you have really killed it, and made you miss matches, and is the core reason (together with problem 4) why you got a duplicate. There is no reason to break here, as the firstif
might be true in one of the next iterations, so you should give that a chance still.
Post a Comment for "Comparing And Adding Items To Array Of Objects"