Caleb Jay
Caleb Jay

Reputation: 2199

Why does this anonymous function return undefined in Javascript?

I'm trying to create a forEach() function that takes an array and a function, then performs the function action on each element of the array. However, when trying to pass the below anonymous function, I get undefined. I tried adding a return to the forEach() function after reading some other posts but then the function doesn't run at all and just returns the first array[i] it receives without modifying it.

function forEach(array, action){
 for(var i = 0; i < array.length; i++)
   action(array[i]);
}

var myArray = [1, 2, 3];
var something = forEach(myArray, function(element){return element++;});
console.log(something)
//undefined

That returns undefined.

function forEach(array, action){
 for(var i = 0; i < array.length; i++)
   return action(array[i]);
}

var myArray = [1, 2, 3];
var something = forEach(myArray, function(element){return element++;});
console.log(something)
//undefined

That returns 1.

What am I missing?

(I am aware a .forEach() function exists, I am trying this as a learning exercise)

Upvotes: 0

Views: 773

Answers (2)

georg
georg

Reputation: 215009

Your foreach implementation is correct - it shouldn't return anything. If you want map (i.e. transform an argument into a new array), you can implement reduce first:

function reduce(array, action, result) {
    forEach(array, function (elem) {
        result = action(result, elem);
    });
    return result;
}

and then, define map via reduce:

function map(array, action) {
    return reduce(array, function (result, elem) {
        return result.concat(action(elem));
    }, []);
}

Putting it all together:

function forEach(array, action) {
    for (var i = 0; i < array.length; i++)
        action(array[i]);
}

function reduce(array, action, result) {
    forEach(array, function (elem) {
        result = action(result, elem);
    });
    return result;
}

function map(array, action) {
    return reduce(array, function (result, elem) {
        return result.concat(action(elem));
    }, []);
}

a = map([1, 2, 3, 4], function (x) {
    return ++x
});
document.write('<pre>' + JSON.stringify(a, 0, 3));

Upvotes: 0

Mike Cluck
Mike Cluck

Reputation: 32511

Your forEach function doesn't return anything. It looks like you're trying your hand at a map implementation. If so, you need to add your results to a new array and return that array.

function map(array, action) { // Renamed forEach to a more suitable name
  var results = [];
  for (var i = 0; i < array.length; i++) {
    results.push(action(array[i]));
  }
  return results;
}

Upvotes: 3

Related Questions