Return Array of Objects which contains and pairs Name and Values from the second Argument

Tell us what’s happening:
Describe your issue in detail here.
Hello Dear friends i need some help/feedback about my code, was trying to solve it on my way, I’m having some issues to solve it.
Thanks a lot for any help,

  **Your code so far**

function whatIsInAName(collection, source) {
let arr1 = 0; 
let arr = 0;
let keys2 = Object.keys(source);
let val2 = Object.values(source);
// Only change code below this line
  
arr = collection.filter(el => Object.keys(el).length >= keys2.length )
for(let i = 0; i < keys2.length; i++){
    
  arr1 = arr.filter(elem => elem.hasOwnProperty(keys2[i]) && Object.values(elem).includes(source[keys2[i]]));    
  
 }

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

whatIsInAName([{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }], { last: "Capulet" });
  **Your browser information:**

User Agent is: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.83 Safari/537.36

Challenge: Wherefore art thou

Link to the challenge:

OK, a few general comments first:

These:

let arr1 = 0; 
let arr = 0;

If these are arrays, why are you initializing them as numbers? Do you even need to initialize them here?

This:

arr = collection.filter(el => Object.keys(el).length >= keys2.length )

I get what you are trying to do here but I’m not sure it is necessary. I may be wrong, but I’d need some convincing.

OK, why isn’t this working? I think the logic is flawed.

You’re filter is checking one property at a time and then overwriting arr1 with the result, if that one key/value pair matches. We don’t care if one k/v pair matches, we need them all to match. I’m also not sure about the use of includes here. It just sees if that value is anywhere. What if that value exists on a different prop? We should be checking for exact k/v pair matches.

The other problem is that this:

arr1 = collection.filter(...

completely overwrites that variable on each pass. It isn’t building up, it will just end up with the filter from the last pass.

function whatIsInAName(collection, source) {
  let arr1 = 0;
  let arr = 0;
  let keys2 = Object.keys(source);
  let val2 = Object.values(source);

  arr = collection.filter((el) => Object.keys(el).length >= keys2.length);
  console.log("* arr", arr);
  for (let i = 0; i < keys2.length; i++) {
    console.log('\n* new i loop', i)
    arr1 = arr.filter((elem) => {
      const res = elem.hasOwnProperty(keys2[i]) &&
        Object.values(elem).includes(source[keys2[i]]);
      console.log("\n*** inside filter, elem", elem)
      console.log('*** keys2[i]', keys2[i])
      console.log('*** Object.values(elem)', Object.values(elem))
      console.log('*** source[keys2[i]]', source[keys2[i]])
      console.log('*** result', res)

      return res;
    });
    console.log('\n* overwriting arr1 with new data')
    console.log("* new arr1", arr1);
  }

  return arr1;
}
console.clear();
const ans = whatIsInAName(
  [
    { first: "Romeo", last: "Montague" },
    { first: "Mercutio", last: null },
    { first: "Tybalt", last: "Capulet" },
    { first: "Ricky-Bobby", last: "Capulet" }
  ],
  { first: "Tybalt", last: "Capulet" }
);

console.log('final result\n', JSON.stringify(ans, null, 2));

I think your logic is off. Reread the instructions and try to put it into pseudo code.

1 Like

Hello Kevin,

Thanks a lot for your feedback, down are all the possible cases and the real request would be . Return an array of Objects which contains the second object pairing its Name and Value.
//… here i have another code but works just for the last case, i need to learn deeper about how object methods works as well … and clear my thoughts I’ve been trying to solve it for some hours…

let arr = [];
  let keys2 = Object.keys(source);
  
  // Only change code below this line
      
  for(let i = 0; i < keys2.length; i++){
      
    arr = collection.filter((elem) => elem.hasOwnProperty(keys2[i]) && Object.values(elem) === Object.values(keys2[i]));    
    
   }

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

…//

whatIsInAName([{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }], { last: "Capulet" }) should return [{ first: "Tybalt", last: "Capulet" }] .

whatIsInAName([{ "apple": 1 }, { "apple": 1 }, { "apple": 1, "bat": 2 }], { "apple": 1 }) should return [{ "apple": 1 }, { "apple": 1 }, { "apple": 1, "bat": 2 }] .

whatIsInAName([{ "apple": 1, "bat": 2 }, { "bat": 2 }, { "apple": 1, "bat": 2, "cookie": 2 }], { "apple": 1, "bat": 2 }) should return [{ "apple": 1, "bat": 2 }, { "apple": 1, "bat": 2, "cookie": 2 }] .

whatIsInAName([{ "apple": 1, "bat": 2 }, { "apple": 1 }, { "apple": 1, "bat": 2, "cookie": 2 }], { "apple": 1, "cookie": 2 }) should return [{ "apple": 1, "bat": 2, "cookie": 2 }] .

whatIsInAName([{ "apple": 1, "bat": 2 }, { "apple": 1 }, { "apple": 1, "bat": 2, "cookie": 2 }, { "bat":2 }], { "apple": 1, "bat": 2 }) should return [{ "apple": 1, "bat": 2 }, { "apple": 1, "bat": 2, "cookie":2 }] .

whatIsInAName([{"a": 1, "b": 2, "c": 3}], {"a": 1, "b": 9999, "c": 3}) should return []

I’ve edited your post for readability. When you enter a code block into a forum post, please precede it with a separate line of three backticks and follow it with a separate line of three backticks to make it easier to read.

You can also use the “preformatted text” tool in the editor (</>) to add backticks around text.

See this post to find the backtick on your keyboard.
Note: Backticks (`) are not single quotes (’).

You are still overwriting arr on each pass. You will only get the result of the filter from the last pass of the for loop.

Some thoughts.

This:

arr = collection.filter((elem) => elem.hasOwnProperty(keys2[i]) && Object.values(elem) === Object.values(keys2[i]));    

not only are you still overwriting your variable, but this:

elem.hasOwnProperty(keys2[i])

is not necessary. If that doesn’t exist, it will just fail the equality check.

Your equality check. Is that right?

First of all, Object.values returns an array - you can’t check reference types like that. But that’s OK, because you don’t need that. Reread the instructions:

...objects that have *matching name and value pairs*...

the pairs have to match. In other words, if source has a certain key (name) then that collection object should have a matching key and matching value. For that key. You should be checking them with the same key. But you should be checking something else with that key.

You don’t need Object.values. You don’t even really need Object.keys, but that can work.

Rather than use filter here (I’m not even sure how to make that work - maybe it’s possible but could get ugly), I would just have a nested for loop. Figure out how to make it work with that and then you can get sneaky.

You might also want to put some thought into the right order of loops.

I still HIGHLY recommend writing this in pseudo code. If you can’t write it out without code, then it’s just going to be harder to write it out with code. Think out the algorithm first, then translate that into code. I don’t know why it is so hard to convince learners of this.