[英]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()
来克隆数组,然后输入替换的值,但是如果我们不使用slice
或concat
,还有另一种方法吗?
我用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.