3

Part of a Javascript course that I'm taking, you're supposed to create your own forEach function that takes two arguments, an array and a callback. It's supposed to pass to the callback each element, its index, and the array itself. Should return undefined. Here is mine:

function myForEach (arr, cb) {
  for(var i = 0; i < arr.length; i++) {
    var elem = arr[i];

    cb(elem, i, arr);
  }
}

Then, you're supposed to reference it in another function and use that to execute some example functions. Particularly, you're supposed to write a function that accepts an array and a callback as arguments and it should pass the callback to every element, its corresponding index, and the array itself. And then it should return a new array where each element in the new array is the return value of the callback. Here is the function in question:

function myMap(arr, cb) {
  var mapped = [];

  mapped.push(myForEach(arr, cb));

  return mapped;
}

I don't understand why (in this example), I'm getting undefined as my value, when the callback being passed should be returning a value:

console.log(myMap([1, 2, 3], function(ele, i, arr){
  return ele * i;
}));
// [0, 2, 6] expected return value

Generally just a bit confused here on balancing what's returning undefined vs. what isn't, and how to actually push a value from the callback into my empty array.

5
  • your forEach doesn't return anything, so that's the same as return undefined Commented Nov 22, 2016 at 1:17
  • The problem is with this line mapped.push(myForEach(arr, cb)); myForEach doesn't return every item, that goes into the callback (in fact it returns nothing which is why you get undefinfed). Here's how to make it work, invoke cb manually and then push it to the mapped array. Like so : jsfiddle.net/2htuer9m Commented Nov 22, 2016 at 1:17
  • "it should pass the callback to every element" - I don't think so :-) Commented Nov 22, 2016 at 1:20
  • @HattanShobokshi ahhh yes - I went over this with a coworker and he also pointed out that you have to run a function as the cb for myForEach that pushes the values to your empty array, and the values you're pushing are just the values of the cb being passed to myMap. Commented Dec 12, 2016 at 1:47
  • Like thisfunction myMap(arr, cb) { var mapped = []; myForEach(arr, function(ele, i, arr) { mapped.push(cb(ele, i, arr)); }); return mapped; } Commented Dec 12, 2016 at 1:47

5 Answers 5

0

There's something about this line:

mapped.push(myForEach(arr, cb));

You're just adding an 'undefined' value (that's what the 'myForEach' function returns) to an empty array.

Sign up to request clarification or add additional context in comments.

1 Comment

Yeah I figured it out - knowing that myForEach is returning undefined. You can see my comment above for the revision. Basically had to switch some callbacks and embed the .push() function in between them.
0

The callback to map and forEach is "what should I do with each element" - and you're not doing the same thing in myMap's each element as in myForEach's each element.

Inside myMap, you want to do this: For each element of arr, call the myMap's callback, then push the result into the result array. (the emphasized part is the myForEach callback you need to use every time for myMap to function).

Meanwhile, if you want to map [1, 2, 3] to [0, 2, 6], the myMap callback is saying multiply each element with its index and return that value. So you absolutely need two different callbacks.

In short,

myForEach(arr, function(element, i, ary) { mapped.push(cb(element, i ary)); });

1 Comment

@david25272: Yeah, that was not well put.
0

The .push() is currently receiving its value directly from myForEach(), which doesn't contain a return statement to provide a value (so, it returns undefined by default).

Being in between the cb and .push(), myForEach() is receiving the results of each cb() and discarding them rather than providing them to myMap().

To avoid that, you'll want move the steps so the .push() and cb() are immediately tied to each other:

mapped.push(cb(elem, i, arr));

You can still use myForEach(), moving it instead around this to perform the iteration, so each elem can be processed by cb and pushed to mapped:

function myMap(arr, cb) {
  var mapped = [];

  myForEach(arr, function (elem, i, arr) {
    mapped.push(cb(elem, i, arr));
  });

  return mapped;
}

Comments

0

The terminology of the map-callback paradigm can be a bit confusing at first.

The map method (e.g. Array.map()) is not the mapping function/callback. It's a loop that applies a callback function to each item of an array.

The callback does the mapping - it maps (or translates) an array item into another value.

So, your callback() function should be taking a single array item (not an array) as an argument, and returning an array item. The map function calls the callback for each item in the array, and assembles the result into a new array. (Alternately, it could return an object, or alter the original array in place).

For example:

var mymap = function(array, callback) {
    var rv = [];
    for(var i=0; i < array.length ; i++) {
        rv.push(callback(array[i]));
    }
    return rv;
}

mycopy = function(element) {
    return element;
}

Then you can use map to duplicate an instance of MyArray:

var oldarray = [...];

var newarray = mymap(oldarray, mycopy);

The point of all this is that you can easily replace mycopy() with something more useful, including functions defined elsewhere or inline anonymous functions:

var positives = mymap(oldarray, Math.abs);

Comments

0

Here is your issue.

console.log(myMap([1, 2, 3], function(ele, i, arr){
  return ele * i;
}));

In the second parameter you are trying to pass an anonymous function. You cannot do this this way due to the hoisting process. Plus there aren't any passed to to this function before it gets executed so it returns undefined.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.