Intermediate Algorithm Scripting - Everything Be True

Tell us what’s happening:
Describe your issue in detail here.
Hi All

Why is this not accepted in false cases? I have printed to the console inside the if statement. The condition is met, the lines are printed - but the function does not return. I can’t see why, it should be as simple as it can get. It’s as if the return statement is somehow broken, but it’s well inside the curly brackets, so I can’t see why it doesn’t work.

Please help. What am I missing? This solution is virtually identical to others posted (that do work) and I’m going crazy trying to find why.

Thanks!

  **Your code so far**
[spoiler]
function truthCheck(collection, pre) {

collection.forEach((arrElement) => {
  if (!arrElement[pre]) {
    return false; 
  }
});
return true;
}
[/spoiler]

truthCheck([{name: "Quincy", role: "Founder", isBot: false}, {name: "Naomi", role: "", isBot: false}, {name: "Camperbot", role: "Bot", isBot: true}], "isBot")
  **Your browser information:**

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:103.0) Gecko/20100101 Firefox/103.0

Challenge: Intermediate Algorithm Scripting - Everything Be True

Link to the challenge:

What you have is a function wrapped in a function. You have the outer function of truthCheck and inside that you have the callback function being passed to forEach. That callback function is (if the value is false) returning false to forEach, it is not returning false from truthCheck. Some methods do something with the return value from the callback - forEach is not one of them.

1 Like

There is a way to make it work, but it would involve and out of scope variable and would be inefficient and messy. I might suggest that there are other methods, like one that figures out if all the elements meet a criteria or if any meet a certain criteria - either of those would work more like what you are expecting and would simplify things.

1 Like

I understand now (I think) that the “return false” inside the forEach function really only returns false PER THE ARRAY ITEM currently being iterated. Is this the case?

Is it even possible to use ForEach here?

Right, but that isn’t the actual problem. I mean, if you had a for loop, you would be returning for each item, and that could work - you are quitting once you have a false item. But here, you have it wrapped in an inner function, so you are just returning from that function, does nothing with that return value, and moves onto the next element.

When in doubt, check the docs. MDN is excellent. Go to this page and look at the section for methods. I do it whenever I can’t remember something.

Yes, thank you so much. I’ve managed to understand it while you were replying (I actually wrote this before I saw your replies, but your replies made it much more clear).

And yes, a simple for loop did the trick. There is probably a way to “level up” the solution using some standard methods but I haven’t looked it too closely yet. In these cases I wonder if it’s worth the effort to keep digging more in to this, or just submit the simple solution with the for loop and move on.

In that vein - wouldn’t a simple solution using a for loop be inherently faster than an advanced (or “advanced”) solution using JS methods?

It would be ever so slightly faster. I mean, very, very tiny bit faster. In this case, we’re measuring it in microseconds. Is that important? What about readability, security, safety, maintainability? Speed is not the only factor. Consider two ways to do the same thing:

const nums = [1, 2, 3]

const squares = []

for (let i = 0; i < nums.length; i++) {
  squares[i] = nums[i] ** 2
}

or

const nums = [1, 2, 3]

const squareANumber = n => n ** 2

const squares = nums.map(squareANumber)

I think the second is better. It is more concise. I can instantly look and know what is happening - map has a semantic meaning - I know that I am creating a new array out of an old array, with each element based on the corresponding element in the previous array. “for” does not tell me that - I need to read the code. I also can read the well named callback function and know exactly what it does. With the first example, I have to read the code. In the first example, I also created an extra variable that I have to manually manipulate, something with which I could make a mistake or someone else might accidentally break. In the second example, the code reads like a story, telling me what it is doing.

I think code should communicate. When possible, use the semantically relevant method. If that doesn’t work, use a for loop. If that doesn’t work, use a while or do while. But I think those should be the order in which you consider them.

Yes, it is a tiny, tiny, tiny bit slower. But if you’re writing for web, 99.99% of the time is spent waiting for user input anyway. And any delay less than 1/10 of a second won’t even be noticed.

Unless you are dealing with massive quantities of data and/or very complex algorithms worry about speed last. I mean, make smart choices, but don’t obsess over it.

Thanks for the detailed reply and explanation and example. This is very much appreciated. I agree with you on everything you said, that code should be maintainable, secure and quickly understandable to the programmer. If I understand correctly, this is what companies today mostly seek when it comes to programming skills.

Still, and this might be just my own inexperience, it was easier for me to read the first example, with the for loop, rather than the second example. Probably because I have spent much more time with for loops than with library functions. map doesn’t mean to me, not immediately at least, what it does to an experienced programmer who’ve used map a zillion times. Creating a new array and mapping its values to the result of a callback function - just understanding what that sentence means takes far more of my own “processing power” (he he) than “this loop does this an X amount of times”. See what I mean? It’s a lower order of thought, easier to grasp.

Again, probably a matter of experience.

From this discussion, your replies and my own, I understand that it is indeed worth the effort to use library methods, even though the instinctive solution (for me, still) are to go “hardcore” with the for loop. I have just now used some other user’s solution as a reference and solved it with the every function. I hope that having spent so much time now on what is essentially a simple problem (algorithmically at least) will pay off in the medium-to-long run.

Thanks so much.

Again, probably a matter of experience.

Yeah, it’s just a matter of familiarity. Once you are more familiar with the callback functions and methods, the second one is much easier to read. And it’s much faster to read - that can make a big difference as you have to read through 10k lines per day.

To be honest, if I saw the first example on a job interview, I would raise my eyebrows. It’s just an ugly solution.

But you have to start somewhere, and for loops are a good place to start. And these methods are really just functions with for loops inside them.

I hope that having spent so much time now on what is essentially a simple problem (algorithmically at least) will pay off in the medium-to-long run.

Yeah, I would expect it will. It’s important not to get caught up on every little thing, but diving a little deeper here and there can be a good thing.

Just give it time, it will all come together.

As to the methods, just familiarize yourself with the most common ones. Understand what they are doing. One of the best ways to do that is two write your own version. I’m sure there are blog posts and videos of people doing that.

In some languages, using array iterators is faster than raw loops because the compiler or interpreter can pull clever optimization tricks

2 Likes