创建我自己的 array.prototype.map 方法。我如何访问该数组?

问题描述 投票:0回答:10

所以我试图创建一种方法来完全模仿

Array.prototype.map()
方法的作用,但有很多地方让我感到困惑。 我认为主要问题在于它的语法。我知道有很多不同的方法可以利用
map
方法,例如:

示例1:

假设我有一个对象数组 -

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"
   }
];

假设我想创建一个函数,返回一个仅包含电影标题及其 imdbRating 的对象列表。在这种情况下,我可以使用

map()
方法:

let newList = movieList.map( (current) ({'title': current['Title'],     
               'rating': current['imdbRating'] }) );

上面的代码行满足了我使用map方法实现目标所需的内容。但是,其他情况的语法可能有所不同

示例2:

let s = [1, 2, 3, 4];

let s2 = s.map( function(item) {
   return item*2;
});

使用映射函数 s2 将返回一个数组,其中每个元素的值都是 s 数组中每个元素的值的两倍。 现在,回到这篇文章的主题,我正在解决的问题给了我这个大纲作为开始:

Array.prototype.myMap = function(callback) {
   let newArray = [];

我知道,当数组调用

myMap
方法时,它会插入 2 个参数:数组和函数。但我无法理解如何将元素上每个回调函数的值具体分配给
newArray
方法中的
myMap
。特别是因为我不知道如何访问原始数组。

据我所知,我的尝试之一是荒谬的,因为我不知道如何访问数组的长度以及调用

myMap
方法的数组本身 -

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;
};

到目前为止,我理解

map()
方法的方式是,它需要 3 个参数、一个数组、一个函数以及将通过该函数放入的元素,而且我不太了解语法,无法迭代数组调用
map
方法,但在我的课程中没有任何地方教过我如何执行此操作,而且我也没有找到任何可以提供此问题解决方案的在线资源。

javascript arrays function ecmascript-6 array.prototype.map
10个回答
7
投票

length
不是一个方法 - 它只是一个属性。并且您需要将
this[i]
传递给
callback
以获得正确的输出。

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);

请注意,改变原型方法是一种非常糟糕的做法,尤其是在存在相同方法时创建新方法。 (

map
具有
myMap
的所有功能以及更多)。


3
投票

这是实际

map
Polyfill 的简化版本。您需要使用
length
来获取
this.length
。并将循环中的当前项、它的索引和数组本身作为参数传递给
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))

注意:

map
方法也采用
thisArg
作为参数。如果你想使用它,你需要
call
callback
thisArg
this

callback.call(thisArg, this[i], i, this);

1
投票

这个答案,但正确保留空项目。

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;
};

0
投票

在这里您可以了解更多关于 javascript 地图功能的信息: https://www.w3schools.com/jsref/jsref_map.asp

实现map方法实际上比你想象的要容易得多。这是一个非常简单的示例,它的功能与 https://www.w3schools.com/jsref/jsref_map.asp:

中的 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 numbers2 = [1, 4, 9];

var squareRoot = numbers2.myMap(function(num) {
    return Math.sqrt(num);
});

console.log(squareRoot); // [ 1, 2, 3 ]

因此,map 方法只是返回一个数组,通过在每个值上运行作为参数给出的指定函数,将其值映射到原始数组的值。

注意: 该方法跳过原始地图函数的可选参数,该参数指定

this


0
投票

这是您的

myMap
函数的工作版本。

模仿这些方法可能会让人感到困惑的是

this
关键字在 javascript 中的工作原理。这是一篇 MDN Reference 文章。

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;
};

0
投票
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;
};

0
投票

您可以利用扩展运算符并执行以下操作:

Map.prototype.slice = function(start, end) {
    return new Map([...this].slice(start, end));
};

使用中:

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 }

您绝对可以以此为基础,因为这仍然有

Array.prototype.slice()
的警告。


0
投票

如果您不想使用

forEach
,也可以使用 
for loop

Array.prototype.myMap = function (callback) {
  let newArr = [];
  this.forEach((item) => {
    let elem = callback(item);
    newArr.push(elem);
  });
  return newArr;
};


0
投票

在 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;
    };

在此自定义函数回调 cb 中,具有三个参数:当前元素、索引和实际数组。

const arr = [1, 2, 3, 4];
//using myMap
arr.myMap((num)=>num)

0
投票

我关于如何使用打字稿进行递归方式的建议

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)];
}
© www.soinside.com 2019 - 2024. All rights reserved.