DEV Community

Dhilip kumar
Dhilip kumar

Posted on

Implementing our own Array.map() method in javascript

If you know howArray.map() works, you can jump here directly.

What is Array.map in javascript?

A map is a built-in function of Arrays in javascript which helps us iterate over each individual element of the array and returns a brand new array.
Enter fullscreen mode Exit fullscreen mode

First let us understand how map behaves,

For Example:


 js
const sample = [1,2,3];
const mapResult = sample.map(function(val, index, array) {
    console.log('val :', val, 'index :', index, 'array :', array);
    return (val * 2);
});


Enter fullscreen mode Exit fullscreen mode

The output of the above snippet will be:

So, we can conclude that, for each value of the array the function gets executed. And the function has access to 3 arguments:

  • The current element that is processed
  • Current element's index
  • Entire Array

We are returningval*2 on every iteration and that gets stored inmapResult.
So,mapResult has [2,4,6] in it and this wont modify the original arraysample.

Thus, whatever that is returned by map during each iteration, will get stored inside a brand new array and the original array remains untouched.

Note: If nothing is returned from the function thenundefined gets stored in the output array.And this array's length will be same as that of the array on which map is done.

If we did not return anything in our previous example then,

map will always return an array.So we don't have to write an explicit return from an Array.map function which is why we use map most of the times to iterate through lists in React.

Lets create our own map method[mymap]

Step 1:

  • We will create a new method[mymap] which allows us to useArray.mymap()
  • In order to use Array.mymap() we have to havemymap()'s definition in Array.prototype.

 js
Array.prototype.mymap = function(){

}


Enter fullscreen mode Exit fullscreen mode

Now we will be able to run[1,2,3].mymap(); which will returnundefined.

Step 2:

  • map is called with function as an argument inside it. (eg:[1,2].map(function(val, index, arr){})). So, ourmymap function should accept a function as an argument.
  • The function in the argument should be called for each value in the array with 3 arguments:
    • The current element
    • Current element's index
    • Entire Array
  • this refers to the array on whichmymap is done. this is the array itself.


js
Array.prototype.mymap = function(callback) {
for (let index = 0; index < this.length; index++) {
callback(this[index], index, this);
}
}
Enter fullscreen mode Exit fullscreen mode




Step 3:

  • Finally, we output the result to a new array and return them.

js
Array.prototype.mymap = function(callback) {
const resultArray = [];
for (let index = 0; index < this.length; index++) {
resultArray.push(callback(this[index], index, this));
}
return resultArray;
}
Enter fullscreen mode Exit fullscreen mode




Output:

Thats it :) we have implemented our own map method.

Share if it helped you :)

Next step: Try using similar approach and create a custom map for objects.

Top comments (10)

Collapse
 
zaky7 profile image
Zakir • Edited
Array.prototype.myFilter = function(callback) {
    const filterArr = [];
    for(let index = 0; index<this.length; index++) {
        if(!!callback(this[index], index, this)) {
            filterArr.push(this[index]);
        }
    }
    return filterArr;
}

Array.prototype.myReduce = function(callback, accumulator) {
    if(this.length < 1) {
        throw new Error("Array is Empty")
    }

    if(!accumulator) {
        if(typeof this[0] === "string") {
            accumulator = '';
        } else if(typeof this[0] === "number") {
            accumulator = 0;
        }
    }

    for(let index=0; index < this.length; index++) {
        accumulator = callback(accumulator, this[index]);
    }
    return accumulator;
}

const names = ['Zakir', 'Rashid', 'Harish'];
const filterNames = names.myFilter(name => name !== 'Zakir');
const statment = names.myReduce((acc, ele) => acc + ele);

console.log(filterNames) // [ 'Rashid', 'Harish' ]
console.log(statment); // Zakir Rashid Harish
Enter fullscreen mode Exit fullscreen mode
Collapse
 
akanshgulati profile image
Akansh

@diliptwit291 The above implementation fails for

[1,2,3, null, , 4].mymap(a => +a);
Enter fullscreen mode Exit fullscreen mode

Gives, different results from map

.mymap => [1, 2, 3, 0, NaN, 4]
.map => [1, 2, 3, null, undefined, 4]
Enter fullscreen mode Exit fullscreen mode
Collapse
 
ashwaniweb profile image
Worried Indian • Edited

Array.prototype.myMap= function (callback) {
let result = this;
for (let index = 0; index < this.length; index++) {
if (this[index] === undefined) {
break;
}
result[index] = callback(this[index], index, this);
}
return result;
};

Collapse
 
kyselberg profile image
Illia Kyselov • Edited

here is i've wrote with context passing

Array.prototype.myMap = function(cb, thisArg) {
const newArray = [];
const that = thisArg || this;
const thatLength = that.length;

for (let i = 0; i < thatLength; i++) {
    const el = cb.call(that, that[i], i, that);
    newArray.push(el);
}

return newArray;
Enter fullscreen mode Exit fullscreen mode

};

Collapse
 
emilianomorghen profile image
Emiliano Morghen

Another solution here.

/**
 * @callback callbackFn
 * @param {object} [thisArg]
 * @return {Array}
 */
Array.prototype.myMap = function (callbackFn, thisArg) {
  let _this = this, 
      i = 0,
      newArr = [],
      callback = (thisArg !== undefined) ? callbackFn.bind(thisArg) : callbackFn;

  for (let e of _this) {
    if (e === undefined || e === null) {
      newArr.push(e);
      continue;
    }

    newArr.push(callback(e, i, _this))
    i++;
  }

  return newArr;
};
Enter fullscreen mode Exit fullscreen mode

It can be argued why the use of for ( of ) instead of the classic for.
I'm interested on the topic too. Share your thoughts

Collapse
 
jvasque profile image
jvasque

Interesting, altough I have a problem where this case not function because others class, use the element 'this' and result in error. I trying resolve it, when I do, I´ll share the results. I commented this in case someone know how to do. Help is welcome.

Collapse
 
prabhukadode profile image
Prabhu

Nice

Collapse
 
dheerajk30 profile image
Dheeraj Khathuria

I have a question, what if you use an arrow operator. It uses global window as this then, why so?

Collapse
 
dhilipkmr profile image
Dhilip kumar

That's due to the property of the arrow function where it binds the Lexical this as its own this. That is the reason why we not use arrow function here

Collapse
 
prabhukadode profile image
Prabhu

Good