Using only for loop and not filter()

Tell us what’s happening:
Describe your issue in detail here.
is there any way to do it using only for loop? i want to understand why it works the way it does without just typing everything that comes to mind.

  **Your code so far**

function whatIsInAName(collection, source) {
  let n=[]
  arrayOfSrc=Object.keys(source) // contains the array of properties of source
  for(let obj of collection){
    for(let propName of arrayOfSrc){
      //if obj hgas the property and the value of the property also matches
      if(obj.hasOwnProperty(propName) && source[propName]==obj[propName]){
        //push the matched object to n
       n.push(obj)
      }
    }
  }
  console.log(n)
  
}
  // whatIsInAName([{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }], { last: "Capulet" });
  whatIsInAName([{ "apple": 1, "bat": 2 }, { "bat": 2 }, { "apple": 1, "bat": 2, "cookie": 2 }], { "apple": 1, "bat": 2 })
  **Your browser information:**

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

Challenge: Wherefore art thou

Link to the challenge:

is there any way to do it using only for loop?

Yes. All those prototype methods are really just disguised loops. They have loops internally so you don’t have to worry about it. There is nothing you can do with filter, map, filter, sort, etc. that you can’t do with a for loop. It just might be messier. I prefer to use those prototype methods whenever I can - they lead to cleaner, safer, and easier to read code. But I agree that trying to do them with for loops can be a good learning tool.

That being said, I see two issues with your code:

  1. You aren’t returning anything. If you don’t return anything, that is the same as returning undefined.
  2. Your logic of when to push… You are seeing if you have a match and then are pushing. That works fine if you have only one key/value pair to check. But in the example case you have there, there are two: { "apple": 1, "bat": 2 }. So, if the first one matches, you push? And then you push again if the next key value pair matches. You should only be pushing if all the key value pairs match. So, you need a way to keep track if they all matched or not.
2 Likes

any hint for what i would need?

I thought that was a hint.

I was able to get it to work by creating a variable to contain a boolean. I set it to true and if I found a non-match, I set it to false. I then (after the key/value pairs were checked) conditionally pushed the current object.

1 Like

im really sorry. im not able to solve it if the source object has more than two properties. i have now spent more than 10 days on this question

Don’t get frustrated. This is tough stuff.

OK, I don’t like blurting out answers, but let me give more of a hint.

First of all, to get this to work the only things I had to change outside of the outer loop is to return the correct value and to properly declare arrayOfSrc.

So, inside the outer loop, we want a boolean flag variable to keep track if in this iteration of the outer loop, if we should or should not include this obj. I like the logic of assuming it is good and then setting it to false if there is a problem.

So, in pseudo code:

loop obj of collection
    variable shouldInclude, set to true // start with the assumption that it is good
    loop propName of arrayOfSrc
         if not found
             set shouldInclude to false // we found a mismatch, so we don't want to add
             break // once we find a mismatch, no point checking the others

    if shouldInclude is still true, then push

This is the outer loop only, not what came before or after.

Does that make sense?

If you’re still stuck, share what you have - it will be easier to advise.

1 Like

Note that the logic of the if statement is the reverse logic of what you have right now.

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.