Intermediate Algorithm Scripting - Wherefore art thou

//Trying to figure out why && does not work here but || does
console.log(keys[i], source[keys[i]], item[keys[i]])
last Capulet Montague
last Capulet null
last Capulet Capulet

All the items have the key last in this test case. The determining factor is the value.
I read source[keys[i]] != item[keys[i]] as if the source value does not equal the item value, return false. (Capulet Montague) and (Capulet null) don't match but are not returning false. Any insight on what im overlooking would be greatly appreciated.

Your code so far

function whatIsInAName(collection, source) {

  let keys = Object.keys(source)
  //console.log(keys)

  return collection.filter(item => {
    for(let i = 0; i < keys.length; i++){

      console.log(keys[i], source[keys[i]], item[keys[i]])
   
      if(!item.hasOwnProperty(keys[i]) && source[keys[i]] != item[keys[i]]){
        return false
      }
    }
    return true

  
  })
  

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

Your browser information:

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

Challenge: Intermediate Algorithm Scripting - Wherefore art thou

Link to the challenge:

it looks like you didn’t follow the rules of the test so I don’t think it makes sense to debug till you have followed the rules.
The original code given was:

function whatIsInAName(collection, source) {
  const arr = [];
  // Only change code below this line


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

And it said you should not modify anything above or below the comment lines.
So please try to rewrite following that rule initially before debugging.

I’ve solved this question already. I was going back through solving them all again and wondering why || works and && doesn’t when they both are basically saying the same thing (I think)…

try putting this clause inside a bracket
I’m not sure if the && is running first or if the != is running first

Tried
[ source [ keys[i] ] ] != [ item[ keys[i] ] ]
and
[source[keys[i]] != item[keys[i]]]

The code is literally just copy and pasted from the first solution. All i did was change || to &&… Am i correct in assuming that it should still yield the same result? Im not to sure what you meant by if && or != is running first. Objects are my weak point, so i am trying to get better by going though the fine details of object problems. Any insight is very much appreciated.

Sorry I didn’t mean square brackets just regular brackets ()

I am saying in your original code perhaps the && is running before the != (the computation of and is done first).
To make sure it doesn’t run first , use brackets

Edit: on rereading your post it almost sounds like you are unsure of what && and || do . So just in case you don’t know, the first one is only evaluating to true when both arguments are true. The second one evaluates to true if any of the arguments are true.

(source[keys[i]] != item[keys[i]])

still yields:
[ { first: ‘Romeo’, last: ‘Montague’ },
{ first: ‘Mercutio’, last: null },
{ first: ‘Tybalt’, last: ‘Capulet’ } ]

No, I fully grasp what && and || do… In this situation we are looking for both property AND value to be equal. That is why I’m unsure why this code doesn’t compute. The other solutions use && as well.

okay so this is what I would expect because your filter ignores everything that both doesn’t have the last key AND doesn’t have Capulet.
So that means everything that has a last key will be returned from the filter.

Edit: sorry I’ve managed to really confuse myself somehow…
I am going to look at this whole question again

Still a bit grey on why anything with the last key would be returned if there is another criteria to be met as well which 2 items don’t match. I apologize that I can’t see it as clearly as you. Still learning.

no actually I’m very confused too.
Your code isn’t what I thought…

Normally filter is used with a function that acts on each item…
but you have a for loop in your filter which shouldn’t be there

Edit: okay now I get the reason for the for loop (because the source can have multiple properties as well)

When I do this, the code works as how I assumed it would, producing the one item…
if(item.hasOwnProperty(keys[i]) && source[keys[i]] === item[keys[i]]){
return true
}

When i flip it like how i originally posted code, it doesn’t…
if(!item.hasOwnProperty(keys[i]) && source[keys[i]] != item[keys[i]]){
return false
}

I think you are right though… Any item that has the last key is getting passed… On the right of the && i can do != or this === and the result still yields all 3 items… Its as if the right side of the && doesn’t matter. source[keys[i]] === item[keys[i]] and source[keys[i]] != item[keys[i]] still passes all 3. How could this be happening?

it is the operator precedence.

a && b != c

will run a && b first then the result is compared to c

Would you mind explaining that statement in terms of this problem. It would really help me to understand that concept better.

boy I’m not doing very well here…

I was wrong, the operator precedence here is === before && (and same goes for != and ==)

okay when I cut up the if statement, it makes more sense to me and it works better

    for(let i = 0; i < keys.length; i++)
    {
      if(!item.hasOwnProperty(keys[i])) 
      {
        return false;
      } else 
      {
        if (source[keys[i]] != item[keys[i]]) 
        {
          return false;
        }
      }
    }
    return true;

This way we are filtering out anything that doesn’t have last
and anything that does have last but doesn’t have the correct value

The above is equivalent to:

  return collection.filter(item => 
  {
    for(let i = 0; i < keys.length; i++)
    {

      if (!item.hasOwnProperty(keys[i]) || (source[keys[i]] != item[keys[I]])) 
      {
          return false;
      }
      
    }
    return true;
  });

That code works perfectly. So, is including the whole statement in a one line conditional not possible due to the precedence of the operators we need to use conflicting with the way we need to write the conditional? I hope that question made sense lol. My main concern is understanding the boundaries of what is possible so i can plan out how to solve problems better in the future.

if you are still trying to compare why the || statement above worked vs the && not working it is not because of my initial guess of operator precedence (it turned out I was wrong about that).

Rather it is because the && forces both the left and right side of the statement to be true to return true which then triggers the if statement to return false (which is a horrible convoluted thing to say).

I just like to write clean logic that I can understand later on frankly.

The code that doesn’t work does the following effectively for last: Capulet
if ( last is not a key && <something that doesn’t matter because the first clause is always going to be false>)
return false;

Because last is always a key, the AND is always false and so the filter always returns true.

Me talking about it is incredibly hard, so just do this.
Change the input to make some of your collection not have a last key at all.
Then you will see the second part of the if start to run…

Yessss… Makes complete sense… Thank you so much!!! On a side note, hbar as in hedera hashgraph?