Defoe
Defoe

Reputation: 371

Javascript forEach not giving same output as a normal for loop

Hello I'm running some tests to see if the output of both is true. The thing is that given these conditions:

var callback = function (num) {
	return num % 2 === 0
}

console.log($$$.any([1, 3, 4], callback) === true)
console.log($$$.any([1, 11, 111], callback) === false)

I have to create a function that gives as a result in both cases true. I did it with a for loop but I can't get the same result with a forEach, why is that?:

// My for loop function:

$$$ = {
		any: function (arr, callback) {
		for (var i = 0, l = arr.length; i < l; i ++) {
				if (callback(arr[i])) {
				return true;
				}
			}
		return false;
		}
}

// My forEach function:

$$$={
	any: function(array, callback){
		array.forEach(function(value){
			// console.log(value)
			if (callback(value)) {
				return true;
			} 
			// return false;
		})
		return false;
	}
}

Upvotes: 0

Views: 349

Answers (1)

Alnitak
Alnitak

Reputation: 339917

In your second version, the return true in the inner callback function only returns from that callback function, and doesn't cause the outer function to return.

The .forEach loop will run to completion, and then the .any function itself always returns false.

FWIW, .forEach isn't really suitable for a .any function because there's no way to terminate the iteration over the elements as soon as a match is found, and it's therefore less efficient than it could be. For example, you might have an array with 10000 elements, but using .forEach it'll keep on looping, even if the very first element satisfied your predicate.

That said, if you really must use .forEach, though, the solution would be:

function all(array, callback) {
    var result = false;
    array.forEach(function(value) {
        if (callback(value)) {
            result = true;
        }
    });
    return result;
}

with a further optimisation possible to at least avoid calling the user supplied callback once a match is found:

function all(array, callback) {
    var result = false;
    array.forEach(function(value) {
        if (!result && callback(value)) {
            result = true;
        }
    });
    return result;
}

NB: JavaScript already has a function that does what you require - Array.prototype.some

Upvotes: 1

Related Questions