繁体   English   中英

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

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

实现在ECMA-262中定义的 array.map()应该很容易,它接受一个函数,这个函数将被3个参数调用:元素值,索引,数组。

但是对于稀疏数组呢? 显然,如果只有索引0,1,2和100,000具有一个元素,并且从索引3到99,999稀疏,我们不希望从索引0迭代到100,000。 我可以考虑使用arr.slice(0)arr.concat()来克隆数组,然后输入替换的值,但是如果我们不使用sliceconcat ,还有另一种方法吗?

我用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用于试用代码,因为这是某种语言的map的另一个名称)

它应该很容易,但有一些特殊的要点。

允许回调函数修改有问题的数组。 不会访问它添加或删除的任何元素。 所以我们似乎应该使用像Object.keys这样的东西来确定要访问的元素。

此外,结果被定义为一个新的数组“按照数组构造函数创建的”,它采用旧数组的长度,因此我们不妨使用该构造函数来创建它。

这是考虑到这些因素的实现,但可能缺少其他一些细微之处:

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

我假设Object.keys按数字顺序返回数组的键,我认为是实现定义。 如果没有,你可以对它们进行排序。

您不需要使用this.slice(0) 您只需将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