Free Code Camp Bonfire Challenge: Where Art Thou

Posted by

The objective of the “Where art thou” challenge was to make a function that “…looks through an array of objects (first argument) and returns an array of all objects that have matching property and value pairs (second argument). Each property and value pair of the source object has to be present in the object from the collection if it is to be included in the returned array.”

Free Code Camp provided the following example, “…if the first argument is [{ first: “Romeo”, last: “Montague” }, { first: “Mercutio”, last: null }, { first: “Tybalt”, last: “Capulet” }], and the second argument is { last: “Capulet” }, then you must return the third object from the array (the first argument), because it contains the property and its value, that was passed on as the second argument.”  Here is the code that is provided as a starting point:


function whereAreYou(collection, source) {
  // What's in a name?
  var arr = [];
  // Only change code below this line

  // Only change code above this line
  return arr;
}

whereAreYou([{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }], { last: "Capulet" });

For this challenge, I had to do a lot of research. Initially, I tried to do the problem using the methods that were suggested by Free Code Camp, however I could only get two of the four test cases to pass. So the plan of action eventually evolved into using object to string and multiple string manipulation techniques to compare the given objects . During my research process, I came across a function called _.isMatch from the underscore.js library  that would have been perfect to use in solving the problem.  It tells you if the keys and values in properties from one object are contained in another object.  However, Free Code Camp’s editor doesn’t support underscore.js yet.  Here’s the solution for the problem using underscore.js :


collection.forEach(collectionItem => {
if(_.isMatch(collectionItem, source) === true){
arr.push(collectionItem);
}
});

Below is the final code  used to solve this problem. I’ve inserted the comments below to help explain the process used. I have to give credit to StackOverFlow user valentina for providing the needle in a haystack algorithm to answer someone’s question of how to test to see if the contents of one array is found in another array. It was a big help in helping me in solving this problem.  It can be found here.


    // convert what we're looking for into a string
    var sourceString = JSON.stringify(source);

    // remove the brackets, because we don't care about those
    sourceString = sourceString.replace("{", "").replace("}", "");

    var sourceArray = sourceString.split(",");
    //console.table(sourceArray);

    // output to console for debugging purposes
    // console.log("source string: " + sourceString);

    // loop through the collection array
    for (var j = 0; j < collection.length; j++) {

        //define collection which is an item of the collection array
        var collectionItem = collection[j];

        // convert this item to a string
        var collectionString = JSON.stringify(collectionItem);

        // remove the brackets, because we don't care about those
        collectionString = collectionString.replace("{", "").replace("}", "");

        // turn the string into an array
        var collectionArray = collectionString.split(",");
        //console.table(collectionArray);

        // only want to push a collectionItem onto the "arr"" array if and only if
        // it contains everything from the sourceArray
        // so create a counter to count how many things were found during the search
        var foundCounter = 0;

        // loop through the source array and look for each source item in the
        // collectionArray
        for (var i = 0; i < sourceArray.length; i++) {
            if (collectionArray.indexOf(sourceArray[i]) !== -1) {
                // the source item was found so increment the counter
                foundCounter++;
            }
        }

        // if the counter equals the size of the source array then all source items were
        // found so push the collection item onto "arr" array
        if (foundCounter === sourceArray.length) {
            arr.push(collectionItem);
        }
    };

    console.table(arr);

    // Only change code above this line
    return arr;
}

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