FreeCodeCamp and JavaScript: Inventory Update

Inventory Update is the next challenge on FreeCodeCamp and it follows the Exact Change challenge.  Here are the requirements:

“Compare and update the inventory stored in a 2D array against a second 2D array of a fresh delivery. Update the current existing inventory item quantities (in arr1). If an item cannot be found, add the new item and quantity into the inventory array. The returned inventory array should be in alphabetical order by item.”

Doesn’t seem too hard…hahaha, famous last words.

As far as hints, it directs you to the definition of a Global Array Object, which I talked about here.

Here is the code they give you to start out with:

function updateInventory(arr1, arr2) {
    // All inventory must be accounted for or you’re fired!
    return arr1;
}
// Example inventory lists
var curInv = [
    [21, “Bowling Ball”],
    [2, “Dirty Sock”],
    [1, “Hair Pin”],
    [5, “Microphone”]
];
var newInv = [
    [2, “Hair Pin”],
    [3, “Half-Eaten Apple”],
    [67, “Bowling Ball”],
    [7, “Toothpaste”]
];
updateInventory(curInv, newInv);

So for example, the output from the two lists above would be:

var updatedInv = [
     [88, “Bowling Ball”],
     [2, “Dirty Sock”],
     [3, “Hair Pin”],
     [5, “Microphone”]
     [3, “Half-Eaten Apple”],
     [7, “Toothpaste”]
];

Hmmm.  Kind of makes me wonder what the office of the person who wrote this looks like…

Anyway, it looks to me like we’re going to use some loops here, comparing the item anmes in the arrays, and if you get a match, adding the numnbers, and if you don’t pushing the new item and number into an array.  I think I’ll use a third array to hold the merged arrays rather than modifying the current inventory array that gets passed.  Obviously, I’ll need to define one, so here we go:

var updatedInv = [];

As in the exact change challenge, I’ll want two loops, so here’s pseudocode:

arr1.foreach(function (subArray) {
     arr2.foreach(function (subArray) {
          if (arr1.itemName === arr2.itemName) {
               add the amounts together;
               push the new amount and the itemName into updatedInv;
          } else {
               push the itemName and amount from arr2 into updatedInv
                                   OR
               push the itemName and amount from arr1 into updatedInv
          }
     }
}
return updatedInv

Looking at that I may end up just modifying arr1 rather than creating a new array because that OR makes me think that’s how I’ll have to do it.  But we’ll see.  This is a work in progress, after all!

Now, another thing to note is that we have nested arrays.  So, let’s look at curInv (which is arr1 in our function) from above:

var curInv = [
    [21, “Bowling Ball”],
    [2, “Dirty Sock”],
    [1, “Hair Pin”],
    [5, “Microphone”]
];

There are four arrays in the curInv array.  To access the 21 in the first array, we would use:

curInv[0][0] = 21

and to access the name of the first item, “Bowling Ball”:

curInv[0][1] = “Bowling Ball”

I need to keep this in mind when designing my loops.

UPDATE: so, here’s my solution, with, as always, my comments!

function updateInventory(arr1, arr2) {
    // All inventory must be accounted for or you’re fired!
  var updatedInv = [];

I created a new array to hold the updated and sorted inventory items.  This was easier than modifying one of the existing arrays.

for(var i = 0; i < arr1.length; i++) {
      for(var x = 0; x < arr2.length; x++) {
         if (arr1[i][1] == arr2[x][1]) {
            console.log(“same”);
             arr1[i][0] = arr1[i][0] + arr2[x][0];
             updatedInv.push([arr1[i][0], arr1[i][1]]);
             arr1.splice(i,1);
             arr2.splice(x,1);
         } else {
             console.log(“different”);
           }
      }
}
    updatedInv = updatedInv.concat(arr1);
    updatedInv = updatedInv.concat(arr2);

This is the heart of the program.  As I noted above I have two loops, but it’s not quite how I pictured it at first.  See, the key here is that we need to compare the SECOND element of each sub-array – that’s the name of the inventory item.  Now, in code, that’s going to be array[x][1].  See, the first value in brackets (the x, here) is going to change as we loop through the array.  The second value, 1, is going to stay the same – because we always want to be looking at the second item.  We won’t be looping through that value.  It’s the same for both arrays – we are comparing element[1] to see if it has the same name.

Now, if it does, we add the FIRST element in the array – the quantities – together.  That would be element[x][0] in my example.  The x loops, the 0 doesn’t.  So, I add the quantities together to get the new total amount.  I then “push” the updated item to the updatedInv array.  Note that we need both the quantity and the name, and they need to be an ordered pair.  In other words, they need to be a subarray, so I add them as [quantity, name].  Now that I’ve updated the quantity, I can get rid of that item, and I use the splice() method to do that.

We’re almost done – When the loop is finished, I have three arrays – updatedInv, which holds only the items that were modified with new quantities; arr1, which holds all the items in the current inventory that weren’t updated; and arr2, which holds all the new items that were added to the inventory and weren’t in there before.  All three are unique – there are no duplicate values, because we took care of that above using splice().  So, to get the updated inventory, we combine all three arrays – using concat(), which we’ve discussed before.

And we’re done!  Well, not quite.  The instructions specify that the array must be returned with the items in alphabetical order.  Now, target=”_blank”>I borrowed a piece of code to do that – this isn’t cheating, because in the real world they have these things called libraries that you can access to get solutions to things you need to do.  For example, splice() and concat() are pieces of re-usable code.  Also, you’ll note that I often look at previous exercises to see if they are similar.  I re-used my code from exact change above in the loops, modifying it as needed.  Finally, there is one key thing when re-using code – make sure you understand it and don’t just plug it in.  There’s two reasons for that – first, so you learn something and can know when and where to use it in the future, and second, because if you don’t, you may end up causing a bug in your code because you used the wrong thing – it works in some cases but not in others, you just haven’t run into any of the others!

  // Sort array alphabetically
  updatedInv.sort(mySorting);
  function mySorting(a,b) {
    a = a[1];
    b = b[1];
    return a == b ? 0 : (a < b ? -1 : 1);
  }

So, this is a sort() function.  It takes the items in the array two at a time – for example, element[0] and element[1], and then sorts them.  Here, though, we want to sort based on the name, not the quantity.  The quantity is the SECOND element in the array (element[1]).  We are sending subarrays as a and b, and we need the second element of each sub array.  So we let a = the second element of the subarray, or a[1].  Same with b.  Finally, we compare the values of a and b.  Remember that letters have a unicode value?  This is what we use to determine greater than / less than.  That last line is shorthand JavaScript, and could have been written:

if (a==b) {
return 0;
} else if(a < b) {
return -1
} else {
return 1
}

See the sort() method for more.

    return updatedInv;
}

Finally, we return the updated inventory.  And we’re done!

Advertisements

One thought on “FreeCodeCamp and JavaScript: Inventory Update

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s