Reputation: 430
So I am trying to create a method that mimic exactly what the Array.prototype.map()
method does and there is a lot I am confused about.
The main problem I suppose comes down to its syntax. I know there are many different ways to utilitize the map
method for instance:
example 1:
let say I have an array of objects -
var movieList = [
{"Title" : "Inception",
"Awards" : "4 oscars",
"Language" : "English",
"imdbRating" : "8.8"
},
{"Title" : "Inception2",
"Awards" : "44 oscars",
"Language" : "English and Spanish",
"imdbRating" : "9.8"
},
{"Title" : "Interstellar",
"Awards" : "10 oscars",
"Language" : "English",
"imdbRating" : "9.5"
}
];
Lets say I want to make a function that returns a list of objects that contains only the title of the movie and its imdbRating. In this case, I can use the map()
method:
let newList = movieList.map( (current) ({'title': current['Title'],
'rating': current['imdbRating'] }) );
the above line of code satisfies what i need to achieve my objective using the map method. However, the syntax can be different for other cases
example 2:
let s = [1, 2, 3, 4];
let s2 = s.map( function(item) {
return item*2;
});
using the map function s2 will return an array that has for each element double the value of each element in the s array. Now, going back to the theme of this post, the problem I am working on gave me this outline to start with:
Array.prototype.myMap = function(callback) {
let newArray = [];
I understand that when an array calls on the myMap
method, it is inserting 2 arguments, the array and a function. But I cannot wrap my head around how I can concretely assign the value of each callback function on the element to the newArray
in the myMap
method. Especially because I do not know how to access the original array.
One of my attempts that I know is ridiculous because I do not know how I can access the length of the array as well as the array itself which calls on the myMap
method-
Array.prototype.myMap = function(callback) {
let newArray = [];
let x = this.length();
for(let i=0; i<x; i++){
let counter = callback();
newArray.push(counter);
}
return newArray;
};
the way I've understood the map()
method thus far, is it takes 3 arguments, an array, a function, and the element that will be put thru the function and I do not know the syntax well enough to iterate over the array that calls on the map
method and nowhere in my course have I been taught how to do this and I have not found any online resource either that offers a solution to this problem.
Upvotes: 5
Views: 11439
Reputation: 335
my proposition on how to doing with recursive way with typescript
Array.prototype.customMap = function customMap<T>(
callback: (element: T, index: number, array: T[], self?: T[]) => T
): T[] {
if (this.length === 0) {
return [];
}
return (([index, result]) => {
return [
callback(
this[this.length - 1 - index],
this.length - 1 - index,
this,
this
),
...result,
];
})(mapWithSize<T>(this.slice(1), callback));
};
function mapWithSize<T>(
sequence: T[],
callback: (element: T, index: number, array: T[], self?: T[]) => T
): [number, T[]] {
return [sequence.length, sequence.customMap(callback)];
}
Upvotes: 0
Reputation: 113
Creating a custom map function in javascript
Array.prototype.myMap = function (cb){
let temp =[];
for(let i = 0; i < this.length; i++){
temp.push(cb(this[i], i, this))
}
return temp;
};
In this custom function callback cb having three arguments is current element, index and actual array.
const arr = [1, 2, 3, 4];
//using myMap
arr.myMap((num)=>num)
Upvotes: 0
Reputation: 505
You can also use forEach
if you don't want to use a for loop
Array.prototype.myMap = function (callback) {
let newArr = [];
this.forEach((item) => {
let elem = callback(item);
newArr.push(elem);
});
return newArr;
};
Upvotes: 0
Reputation: 139
Like this answer, but correctly preserves empty items.
Array.prototype.map = function (callback, thisArg) {
let arr = [];
const len = this.length;
for (let i = 0; i < len; i++) {
if (i in this) arr.push(callback.call(thisArg, this[i], i, this));
else arr.length++;
}
return arr;
};
Upvotes: 1
Reputation: 21
You could take advantage of the spread operator and do something like this:
Map.prototype.slice = function(start, end) {
return new Map([...this].slice(start, end));
};
And in use:
const testMap = new Map([["a", 1], ['b', 2], ["c", 3], ["d", 4], ["e", 5]]);
console.log(testMap); // Map(5) { 'a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5 }
console.log(testMap.slice(0, 2)); // Map(2) { 'a' => 1, 'b' => 2 }
You can definitely build upon this since this still has the caveats of Array.prototype.slice()
.
Upvotes: 0
Reputation: 31
Array.prototype.mappy = function (callback, thisArg) {
let newArray = [];
for (let i = 0; i < this.length; i++) {
if (i in this) newArray.push(callback.call(thisArg, this[i], i, this));
else newArray.push(undefined);
}
return newArray;
};
Upvotes: 0
Reputation: 353
Here is a working version of your myMap
function.
A part of imitating these methods that may confuse people is how the this
keyword works in javascript. Here is an MDN Reference article.
Array.prototype.myMap = function(callback, thisArg) {
let newArray = [];
let x = this.length;
for(let i=0; i<x; i++){
let counter = callback.call(thisArg, this[i], i, this);
newArray.push(counter);
}
return newArray;
};
Upvotes: 0
Reputation: 35222
This is simplified version of the actual map
Polyfill. You need to get the length
using this.length
. And pass the current item in loop, it's index, and the array itself as a parameter to callback
Array.prototype.myMap = function(callback, thisArg) {
const newArray = [];
const length = this.length;
for (let i = 0; i < length; i++) {
let value = callback(this[i], i, this); // call with proper arguments
newArray.push(value);
}
return newArray;
};
const arr = [1, 2, 3];
console.log(arr.myMap(a => a * 2))
Note: map
method also takes a thisArg
as parameter. If you want to use that, you need to call
the callback
with thisArg
as this
callback.call(thisArg, this[i], i, this);
Upvotes: 4
Reputation: 1091
Here is where you can learn about javascript map function more: https://www.w3schools.com/jsref/jsref_map.asp
Implementing map method is actually quite easier than you think. Here is a really simple example that would do exactly what the map method do from https://www.w3schools.com/jsref/jsref_map.asp:
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 numbers2 = [1, 4, 9];
var squareRoot = numbers2.myMap(function(num) {
return Math.sqrt(num);
});
console.log(squareRoot); // [ 1, 2, 3 ]
So, the map method simply returns an array by whose values map to the original array's values by running a specified function given as an argument on each of the values.
Note: The method skips the optional parameter of the original map function which specifies what will be the this
value
Upvotes: 0
Reputation: 44105
length
is not a method - it's just a property. And you need to pass this[i]
to the callback
for the correct output.
Array.prototype.myMap = function(callback) {
let newArray = [];
let x = this.length;
for (let i = 0; i < x; i++) {
let counter = callback(this[i]);
newArray.push(counter);
}
return newArray;
};
let arr = [1, 2, 3];
arr = arr.myMap(e => e * 2);
console.log(arr);
Please note it's quite bad practice to mutate the prototype methods - and especially creating a new one when an identical method exists. (map
has all the functionality of myMap
plus more).
Upvotes: 8