Skip to content Skip to sidebar Skip to footer

Foreach/for...in Not Returning Values?

So I have a little bit of confusion, I'm solving a challenge on freeCodeCamp. The challenge reads as follows Everything Be True Check if the predicate (second argument) is truthy

Solution 1:

As the other answers explain, this is meaningless:

collection.forEach(function () {
  // do somethingreturnfalse;
});

because array#forEach simply does not care for the return value of its worker function. It just executes the worker function for each array element.

You could use the worker function to set an outer variable:

functiontruthCheck(collection, pre) {
  var allAreTruthy = true;
  collection.forEach(function (elem) {
    // if this ever flips allAreTruthy to false, it will stay false
    allAreTruthy = allAreTruthy && elem[pre];
  });
  return allAreTruthy;
}

But there are better ways to express this.

Check if the predicate (second argument) is truthy on all elements of a collection (first argument).

Could be paraphrased as "Every element of the collection has a truthy value at a particular key."

functiontruthCheck(collection, pre) {
  return collection.every(function (elem) { return elem[pre]; });
}

Could be paraphrased as "None of the elements of the collection have a falsy value at a particular key (or are missing the key entirely)."

Or, since an Array#none method does not actually exist, "There aren't some elements of the collection that have a falsy value at a particular key."

functiontruthCheck(collection, pre) {
  return !collection.some(function (elem) { return !elem[pre]; });
}

The advantage of using Array#some is that it stops iterating the array as soon as the condition it seeks for is fulfilled. If your array had many elements this would mean improved performance. For short arrays there's not a lot of difference to using Array#every or Array#forEach.

The above is semantically equivalent to

functiontruthCheck(collection, pre) {
  var i;
  for (i = 0; i < collection.length; i++) {
    if (!collection[i][pre]) returnfalse;
  }
  returntrue;
}

Since JS objects simply return undefined when you access a key that has not been set, a check for hasOwnProperty is superfluous here.

Solution 2:

You can't return anything from a ForEach loop. It will return undefined by default.

As the official documentation, Array.prototype.forEach() - JavaScript | MDN, says:

There is no way to stop or break a forEach() loop other than by throwing an exception. If you need such behavior, the forEach() method is the wrong tool, use a plain loop instead. If you are testing the array elements for a predicate and need a Boolean return value, you can use every() or some() instead.

So you can use a very simple for..in loop, for example:

for(var c in collection){
    // Do whatever you want
} 

Solution 3:

[collection].forEach of javascript does not work like an ordinary loop. There is no way to prematurely end it not unless you make it throw an exception.

The behavior that you are expecting is what you would expect out of a javascript for loop but since forEach uses callback functions for each looped object, then you are only exiting the callback function instead of the forEach. Also it is worth noting that in your code, the you have a for loop which has a return in it. The return block in this loop only breaks this loop and not the forEach (which I have mentioned earlier, cannot be prematurely terminated unless otherwise)

As you can see forEach is mostly meant to iterate all elements instead of conditional checks per iterated element.

Solution 4:

functiontruthCheck(collection, pre) {
  return collection.every(function (person) { return !!person[pre]; });
}

Solution 5:

you execute a function on each element of the collection. This function checks that element an returns something. But that returned value does not affect the result of the outer function. Since the outer function does not depend on the inner function your result is allways true.

if you define a variable, set this to false and return that variable at the end would works but it would be inefficient. Lets think of the following scenario. You found one element which does not has the target key. So right now you should return but you can't. You have to working yourself through the whole collection. The forEach loop does not give you the chance to exit without a mess. Thus a better idea is the for loop. Your can exit exit the for loop if found what you were looking for

a slightly easier way would be:

functiontruthCheck(collection, pre) {
    //iterate thrugh your collectionfor (var c in collection){
        //get keys of element as an array and check if pre is in that arrayif( Object.keys(collection[c]).indexOf(pre) == -1){
            // pre was not foundreturnfalse;
        }
    }
    returntrue;
}

Post a Comment for "Foreach/for...in Not Returning Values?"