Intermediate Algorithm Scripting: Wherefore art though

Tell us what’s happening:
Hi Everyone,
For this problem, we are given a function with two arguments. The first argument (collection) is an array of objects and the second argument (source) is an object containing a list of properties (1 or more) and their associated values.

We want to filter our first argument and include only those objects which contain all of the properties and values of the second argument.

Where I am having trouble is with iterating through the second argument while at the same time iterating through the first argument, and checking for matching values.

If the second argument only contained one property, i could solve the problem as follows:

arr = collection.filter(x => x[Object.keys(source)] === source[Object.keys(source)]) 

I then tried the following code, but the problem it has is that it passes as true if the object contains any of the objects that we want.

    let finalArr = [ ]

     for(const x in source) {
      finalArr = collection.filter(y => y[x] == source[x])
      console.log(x)
       }
      console.log(finalArr)

I guess my question is, how do I get the code to run through all the properties in our second argument (source), and only pass true if all of those properties are contained with matching values. I feel like I’m on the right path, but maybe my brain is getting discombobulated with multiple itterations happening at the same time.

Your code so far

function whatIsInAName(collection, source) {
  console.log(source)
  
  var arr = [];
  let finalArr = [];
  
for(const x in source) {
  finalArr = collection.filter(y => y[x] == source[x])
  console.log(x)
}
let newArr = [];

arr = collection.filter(x => x[Object.keys(source)] === source[Object.keys(source)])
console.log(arr)

return finalArr;
}



whatIsInAName([{ "apple": 1 }, { "apple": 1 }, { "apple": 1, "bat": 2 }], { "apple": 1 });


Your browser information:

User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36.

Challenge: Wherefore art thou

Link to the challenge:

Hello~!

It looks like you’ve got a very solid grasp on using some of the prototype functions built in to JavaScript. Without giving too much of a hint, there is another Object.prototype function that is very helpful (similar to Object.keys). :slight_smile:

1 Like

Thanks so much!! I will try this tonight :slight_smile:

1 Like

Thanks very much @nhcarrigan!! I’m guessing you were referring to Object.values. I solved the problem, though, in what I feel is a needlessly longwinded manner haha. This is my solution below. Is there some way I could make this simpler?

function whatIsInAName(collection, source) {
  //console.log(source)
  
  var arr = [];
  let finalArr = [];

  
  let collectionTokenArr = [];
  let combinedSourceArr = [];


  let sourceKeys = Object.keys(source);
  // [ 'apple', 'bat' ]
  let sourceValues = Object.values(source);
  // [ 1, 2 ]
    for(let l = 0; l < sourceKeys.length; l++) {
      console.log(sourceKeys[l] + sourceValues[l]);
      combinedSourceArr.push(sourceKeys[l] + sourceValues[l]);
    }
    console.log(combinedSourceArr);
    // [ 'apple1', 'bat2' ]



for(let j in collection) {
  console.log(collection[j]);
  // Each seperate object from collection

  let objectKeys = Object.keys(collection[j]);
  let objectValues = Object.values(collection[j]);
  let temporaryCollectionTokenArr = [];
    // contains Key and Value combination for collection[j]
  
  for(let k = 0; k < objectKeys.length; k++) {
    temporaryCollectionTokenArr.push(objectKeys[k] +    objectValues[k]);
    console.log(objectKeys[k] + objectValues[k]);
    
  }
  collectionTokenArr.push(temporaryCollectionTokenArr);
    // pushing Key and Value combination for collection[j] into a permanant array.  This allows for the key and value combination of each object to be represented in it's own array inside collectionTokenArr.
  
}

// We now have a representation of the key and values of each object, as well as the source.  We now just have to see if these match using the formula bellow.  


 function amIInsideYou(arr1, arr2) { 
      return arr1.every(item => arr2.includes(item)) 
} 

let hopefullyFinalArr = [];
  for(let m = 0; m < collectionTokenArr.length; m++) {
 if(amIInsideYou(combinedSourceArr, collectionTokenArr[m])) {hopefullyFinalArr.push(collection[m])}
}
console.log(hopefullyFinalArr);
 // console.log(amIInsideYou(sourceValues, collectionValues))
  
 
return hopefullyFinalArr;
}

Actually, I was thinking of Object.entries. :sweat_smile:

Your solution works, though - and that is priority number 1. From what I’ve seen, the length of your code is fairly irrelevant. What matters, after it works, is how efficient it is (how long it takes to run) and how readable it is (if I need to look at your code, can I easily understand it?). :slightly_smiling_face:

Thanks @nhcarrigan!! haha, I will look into Object.entries :slight_smile: And that makes sense, thanks a lot!