Wherefore Art Thou Help. Very Confused

I’ve been at this problem for a little while and am not making much progress.

Here’s the link to the challenge: https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/intermediate-algorithm-scripting/wherefore-art-thou

Here’s my code:

function whatIsInAName(collection, source) {
  // What's in a name?
  var arr = [];
  // Only change code below this line
  Object.keys(source).forEach(key => {
    let filtered = collection.filter(obj => {
      if(Object.keys(obj).length >= Object.keys(source).length) {
        if (obj.hasOwnProperty(key) && source[key] === obj[key]) {
          return obj;
        }
      }
    });
    if (a) {
      filtered.forEach(obj => {
        arr.push(obj)
      })
    } 
  });
  // console.log(arr);
  // Only change code above this line
  return arr;
}
// whatIsInAName([{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }], { last: "Capulet" });
whatIsInAName([{"a": 1, "b": 2, "c": 3}], {"a": 1, "b": 9999, "c": 3})

It doesn’t seem that my code compares every object in collection with every object in source the way that I want it to. I don’t understand why this is happening. For Example, If you run this code against the final “iteration” (containing the “b”: 999 pair), it still pushes the object even though I’m clearly checking if the object has both the same properties and values in the If state. I’m thoroughly confused :sweat_smile: Any hints are much appreciated!

can you post a link to the challenge? Hard to remember what it was all about…

I made an edit with a link to the challenge

Ok. I edited my post above to push the objects to the arr array. I see that there are duplicates getting pushed, but I still don’t understand why the last test i.e.

whatIsInAName([{“a”: 1, “b”: 2, “c”: 3}], {“a”: 1, “b”: 9999, “c”: 3})

still pushes its object even though I’m checking if the values are the same here:

if (obj.hasOwnProperty(key) && source[key] === obj[key]) {
          return obj;
       }

You are only checking if the first key in obj is having the same value as the first key in source. You then immediately return the obj (side comment: did you know that filter only needs you to return true or false in order for it to keep or discard the obj?)
So filtered ends up having all the objects whose first key matched.
And all the objects whose second key matched.
And all the objects whose third key matched.
(As you are repeating the code for each source key)

I’ve read in other posts that you need to match ALL of the key/property values from the objects inside of collection with those inside of source, but I haven’t wrapped my head around how to do that.

This is some new code I came up with now that I feel would do the trick but it still doesn’t seem to be working.

  var keys = Object.keys(source);
  arr = collection.every(obj => {
    let k =  keys.every(key => {
      if (obj.hasOwnProperty(key) && source[key] === obj[key]) {
        console.log(source[key], obj[key]);
        return obj;
      }
    });
    return k;
  });
  // console.log(arr); 
  // Only change code above this line
  return arr;

I just edited my code to this:

  var keys = Object.keys(source);
  arr = collection.filter(obj => {
    let k =  keys.every(key => {
      if (obj.hasOwnProperty(key) && source[key] === obj[key]) {
        // console.log(source[key], source, obj[key], obj);
        return obj;
      } 
    });
    return k;
  });

I changed the outer every loop on collection to filter and it passed the test. I think I’ve written similar code in past attempts, but this actually just worked. However, I feel I just got lucky here. I’m still trying to understand why this works over what I’ve written before. Thank you for your guidance @hbar1st

here, see if this helps you understand the code:

1 Like

Yes, this does help my understanding. I think my misunderstanding was really with using forEach vs. every. Previously, I kept using for loops and forEach because I thought that each prop/value pair was being compared appropriately. Apparently every is a better choice in this case. Thank you for your help @hbar1st.

1 Like