Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Implementation of Native JavaScript Methods (forEach, Map, Filter, Reduce, Every, Some)
'use strict';
/*****************NATIVE forEACH*********************/
Array.prototype.myEach = function(callback) {
for (var i = 0; i < this.length; i++)
callback(this[i], i, this);
};
//tests
var arr = ['biggy smalls', 'bif tannin', 'boo radley', 'hans gruber'];
arr.myEach(function(word) {
console.log(word);
});
//biggy smalls
//bif tannin
//boo radley
//hans gruber
/*****************NATIVE MAP*************************/
Array.prototype.myMap = function(callback) {
arr = [];
for (var i = 0; i < this.length; i++)
arr.push(callback(this[i], i, this));
return arr;
};
//tests
var arrs = ['dic tanin', 'boo radley', 'hans gruber'];
var numbers2 = [1, 4, 9];
var goodT = arrs.myMap(function(n) {
return n;
});
var squareRoot = numbers2.myMap(function(num) {
return Math.sqrt(num);
});
console.log(goodT); // [ 'dic tanin', 'boo radley', 'hans gruber' ]
console.log(squareRoot); // [ 1, 2, 3 ]
/*****************NATIVE FILTER*************************/
Array.prototype.myFilter = function(callback, context) {
arr = [];
for (var i = 0; i < this.length; i++) {
if (callback.call(context, this[i], i, this))
arr.push(this[i]);
}
return arr;
};
//tests
var numbers = [1, 20, 30, 80, 2, 9, 3];
var newNum = numbers.myFilter(function(n) {
return n >= 10;
});
console.log(newNum); // [ 20, 30, 80 ]
/*****************NATIVE REDUCE*************************/
Array.prototype.myReduce = function(callback, initialVal) {
var accumulator = (initialVal === undefined) ? undefined : initialVal;
for (var i = 0; i < this.length; i++) {
if (accumulator !== undefined)
accumulator = callback.call(undefined, accumulator, this[i], i, this);
else
accumulator = this[i];
}
return accumulator;
};
//tests
var numbers3 = [20, 20, 2, 3];
var total = numbers3.myReduce(function(a, b) {
return a + b;
}, 10);
console.log(total); // 55
var flattened = [
[0, 1],
[2, 3],
[4, 5]
].reduce(function(a, b) {
return a.concat(b);
});
console.log(flattened); //[ 0, 1, 2, 3, 4, 5 ]
/*****************NATIVE EVERY*************************/
Array.prototype.myEvery = function(callback, context) {
for (var i = 0; i < this.length; i++) {
if (!callback.call(context, this[i], i, this))
return false;
}
return true;
};
//tests
var passed = [12, 5, 8, 130, 44].myEvery(function(element) {
return (element >= 10);
});
console.log(passed); // false
passed = [12, 54, 18, 130, 44].myEvery(function(element) {
return (element >= 10);
});
console.log(passed); // true
passed = [12, 54, 18, 130, 44].myEvery(function(element) {
return (element >= 13);
});
console.log(passed); // false
/*****************NATIVE SOME*************************/
Array.prototype.mySome = function(callback, context) {
for (var i = 0; i < this.length; i++) {
if (callback.call(context, this[i], i, this))
return true;
}
return false;
};
//tests
var passed = [12, 5, 8, 130, 44].mySome(function(element) {
return (element >= 200);
});
console.log('some: ' + passed); //some: false
var passed = [12, 5, 8, 130, 44].mySome(function(element) {
return (element >= 100);
});
console.log('some: ' + passed); //some: true
@jacekjastrzebski
Copy link

jacekjastrzebski commented Apr 16, 2016

Thank you very much! This is very informative!

Loading

@Nannapaneni
Copy link

Nannapaneni commented Dec 13, 2016

Thanks for your time and effort. Great job!

Loading

@yajurvendrasinh
Copy link

yajurvendrasinh commented Feb 18, 2017

Awesome \m//

Loading

Copy link

ghost commented Apr 28, 2017

Appreciate what you did! It all makes so much sense now. Very useful!

Loading

@Ghanshyam-K-Dobariya
Copy link

Ghanshyam-K-Dobariya commented Sep 21, 2017

@alexhawkins

Your implementation of myEach fails for below array.

var arr = [0,undefined,2]; arr[10] = 10;
arr.myEach(function(word) {
    console.log(' ==> ', word);
});

You need to differentiate between arr[1] & arr[3].
Compare output of your code with below code

arr.forEach(function(word) {
    console.log(' ==> ', word);
});

Loading

@nersoh
Copy link

nersoh commented Oct 10, 2017

Good job! 👏

Loading

@chriszhangusc
Copy link

chriszhangusc commented Nov 3, 2017

This is awesome! Worth more scores for sure!

Loading

@fuermosi777
Copy link

fuermosi777 commented Dec 4, 2017

line 66: why not just let accumulator = initialValue?

Loading

@onso89
Copy link

onso89 commented Dec 9, 2017

How can we check other methods on our own? How to find JS build in methods definitions?

Loading

@PranavRudra
Copy link

PranavRudra commented Jan 15, 2018

@Ghanshyam-K-Dobariya

You can solve that problem by doing

if (i in this)
  callback(this[i], i, this);

That way, since each array element's index is a property of the array, indices 3-9 won't result in undefined being printed

Loading

@mahmoudZakaria90
Copy link

mahmoudZakaria90 commented Jan 31, 2018

@fuermosi777 or we can abstract it to
if(!accumulator)

Loading

@bassettyambica
Copy link

bassettyambica commented Mar 1, 2018

Awesome work!!

Loading

@martianmartian
Copy link

martianmartian commented Mar 6, 2018

Many native array functions, including Array.map and Array.filter, are therefore written as pure functions. They take in an array reference and internally, they copy the array and work with the copy instead of the original.

https://codeburst.io/explaining-value-vs-reference-in-javascript-647a975e12a0

nice work but this isn't it

Loading

@martianmartian
Copy link

martianmartian commented Mar 6, 2018

Loading

@Tellisense
Copy link

Tellisense commented Mar 11, 2018

thank you very much!!

Loading

@prabhic
Copy link

prabhic commented Mar 21, 2018

Thanks for that, very easy to understand the behaviour, instead of reading a big document

Loading

@brinthsanti
Copy link

brinthsanti commented Apr 26, 2018

Its really useful bro....

Loading

@goelnavneet2006
Copy link

goelnavneet2006 commented Jun 3, 2018

good job done!

Loading

@rakesh-nayak
Copy link

rakesh-nayak commented Aug 23, 2018

Very useful!!

Loading

@godblessmensah
Copy link

godblessmensah commented Nov 26, 2018

This goes to confirm this article javascript performance mistakes . Its more helpful to use the plain old for loop than the new array functions in es6.

Loading

@stanlee94
Copy link

stanlee94 commented Jan 21, 2019

Cool! Been looking for this for a while.

Loading

@usmanajmal
Copy link

usmanajmal commented Jan 26, 2019

@alexhawkins How do you use context in myFilter and why does your solution work when context is undefined as it is in your tests.

Loading

@supposedly
Copy link

supposedly commented Feb 4, 2019

@usmanajmal someFunction.call(), aka Function.prototype.call(), uses its first argument as "this". That means that callback.call(context, ...) is a direct equivalent to callback.bind(context)(...), which in turn says that any instances of this within callback will refer to context.

As you can probably tell, it has little to no relevance here... so TBQH I'm not quite sure why this gist's author used .call() in such a manner. Rather than defining myFilter(callback, context) and then doing callback.call(context, ...), it would be much preferable (as far as I can tell) to define myFilter(callback) and simply do callback(...); if the user needs to bind to context, they can pass the callback in as callback.bind(context) without forcing the myFilter function to care about it.
(Same goes for myReduce()... would be simpler within it to do callback(...) rather than callback.call(undefined, ...).)

Loading

@ved740
Copy link

ved740 commented Mar 13, 2019

Wow.. You made it look so easy !! GREAT

Loading

@kshitijnagpal
Copy link

kshitijnagpal commented Mar 17, 2019

Good work, thanks!

Loading

@sagarrock101
Copy link

sagarrock101 commented Jun 28, 2019

what has "callback(this[i], i, this)"; have to do in the code??

Loading

@anks333
Copy link

anks333 commented Jul 8, 2019

thanks,

Loading

@anks333
Copy link

anks333 commented Jul 8, 2019

Can you explain how Map data structure is implemented in JS, Considering Non-Primitive data type as key.

Loading

@priyankamalviya
Copy link

priyankamalviya commented Aug 24, 2019

everything looks great except, in reduce, why do we need all these parameters when we are binding the reduceFn context? [undefined, accumulator, this[i], i, this]? Any explanations please? I noticed, this breaks without the undefined

Loading

@NexGenUA
Copy link

NexGenUA commented Oct 4, 2019

myReduce function is wrong

[undefined,null,'3',4,5].reduce((acc, cur) => acc*cur) // NaN; 
[undefined,null,'3',4,5].myReduce((acc, cur) => acc*cur) // 0;

correct:

Array.prototype.myReduce = function(...rest) {
  
  if (!rest || typeof rest[0] !== 'function') {
    throw new TypeError(`${rest[0]} is not a function`);
  }

  const callback = rest[0];
  const arr = this;
  let thumb = rest.length > 1;
  let accumulator = thumb ? rest[1] : arr[0];

  for (let i = 0; i < arr.length; i++) {
    if (thumb) {
      accumulator = callback(accumulator, arr[i], i, arr);
    } else thumb = true;
  }
  return accumulator;  
}

Loading

@vihangmi10
Copy link

vihangmi10 commented Oct 4, 2019

Thanks for helping us out! Great one!

Loading

@abhijithsreenivas
Copy link

abhijithsreenivas commented Jun 24, 2020

Seriously Great one ☝️. Thanks!

Loading

@jialihan
Copy link

jialihan commented Mar 7, 2021

My reduce implement: just a little bit difference:

Array.prototype.myReduce = function (fn, initialValue) {
    var accumulator = initialValue || this[0];
    for (var i = 0; i < this.length; i++) {
        if (!initialValue && i === 0) {
            // when initialValue is not provided
            continue;
        }
        accumulator = fn.call(null, accumulator, this[i], i, this);
    }
    return accumulator;
};

Loading

@mAminP
Copy link

mAminP commented Aug 27, 2021

Good work, thanks!

Loading

@hs2504785
Copy link

hs2504785 commented Sep 22, 2021

Very nice

Loading

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment