简体   繁体   English

如何为稀疏数组实现Javascript ECMA 5的array.map()?

[英]How to implement Javascript ECMA 5's array.map() for sparse array?

It should be quite easy to implement array.map() that is defined in ECMA-262 , which takes a function and this function will be called by 3 arguments: element value, index, the array. 实现在ECMA-262中定义的 array.map()应该很容易,它接受一个函数,这个函数将被3个参数调用:元素值,索引,数组。

But what about for sparse array? 但是对于稀疏数组呢? Obviously we don't want to iterate from index 0 to 100,000 if only index 0, 1, 2, and 100,000 has an element and otherwise is sparse from index 3 to 99,999. 显然,如果只有索引0,1,2和100,000具有一个元素,并且从索引3到99,999稀疏,我们不希望从索引0迭代到100,000。 I can think of using arr.slice(0) or arr.concat() to clone the array, and then put in the replaced values, but what if we don't use slice or concat , is there another way to do it? 我可以考虑使用arr.slice(0)arr.concat()来克隆数组,然后输入替换的值,但是如果我们不使用sliceconcat ,还有另一种方法吗?

The solution I came up with using slice() is: 我用slice()提出的解决方案是:

Array.prototype.collect = Array.prototype.collect || function(fn) {
    var result = this.slice(0);

    for (var i in this) {
      if (this.hasOwnProperty(i))
        result[i] = fn(this[i], i, this);  // 3 arguments according to ECMA specs
    }
    return result;
};

( collect is used to try out the code, as that's another name for map in some language) collect用于试用代码,因为这是某种语言的map的另一个名称)

It should be easy, but there are a few peculiar points. 它应该很容易,但有一些特殊的要点。

The callback function is allowed to modify the array in question. 允许回调函数修改有问题的数组。 Any elements it adds or removes are not visited. 不会访问它添加或删除的任何元素。 So it seems we should use something like Object.keys to determine which elements to visit. 所以我们似乎应该使用像Object.keys这样的东西来确定要访问的元素。

Also, the result is defined to be a new array "created as if by" the array constructor taking the length of the old array, so we might as well use that constructor to create it. 此外,结果被定义为一个新的数组“按照数组构造函数创建的”,它采用旧数组的长度,因此我们不妨使用该构造函数来创建它。

Here's an implementation taking these things into account, but probably missing some other subtleties: 这是考虑到这些因素的实现,但可能缺少其他一些细微之处:

function map(callbackfn, thisArg) {
  var keys = Object.keys(this),
    result = new Array(this.length);

  keys.forEach(function(key) {
    if (key >= 0 && this.hasOwnProperty(key)) {
      result[key] = callbackfn.call(thisArg, this[key], key, this);
    }
  }, this);

  return result;
}

I am assuming Object.keys returns the keys of the array in numerical order, which I think is implementation defined. 我假设Object.keys按数字顺序返回数组的键,我认为是实现定义。 If it doesn't, you could sort them. 如果没有,你可以对它们进行排序。

You don't need to use this.slice(0) . 您不需要使用this.slice(0) You can just make result an array and assign values to any index: 您只需将result作为数组并将值分配给任何索引:

Array.prototype.collect = Array.prototype.collect || function(fn) { 
  var result = [];
  for(var i in this) {
    if (this.hasOwnProperty(i)) { 
      result[i] = fn(this[i]);
    }
  }
  return result;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM