如何实现Javascript ECMA 5';s array.map()用于稀疏数组?
它应该很容易实现如何实现Javascript ECMA 5';s array.map()用于稀疏数组?,javascript,Javascript,它应该很容易实现array.map(),也就是说,它接受一个函数,这个函数将由3个参数调用:元素值、索引、数组 但是对于稀疏数组呢?显然,如果只有索引0、1、2和100000有一个元素,或者从索引3稀疏到99999,我们不希望从索引0迭代到100000。我可以考虑使用arr.slice(0)或arr.concat()克隆数组,然后输入替换的值,但是如果我们不使用slice或concat,还有其他方法吗 我使用slice()提出的解决方案是: Array.prototype.collect = A
array.map()
,也就是说,它接受一个函数,这个函数将由3个参数调用:元素值、索引、数组
但是对于稀疏数组呢?显然,如果只有索引0、1、2和100000有一个元素,或者从索引3稀疏到99999,我们不希望从索引0迭代到100000。我可以考虑使用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
的另一个名称)您不需要使用此.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;
}
这应该很容易,但也有一些特殊的地方 允许回调函数修改有问题的数组。它添加或删除的任何元素都不会被访问。因此,我们似乎应该使用类似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以数字顺序返回数组的键,我认为这是实现定义的。如果没有,您可以对它们进行排序。
var result=[]代码>应该足够了。。。为什么要克隆阵列?还要注意,在某些浏览器中,length
可能是可枚举的。如果我们设置result=[]
,然后设置result[0]=1
,然后设置result[10000]=2
,它们是否相同,那么它就是一个稀疏数组,就像原始数组一样?所有未设置的索引都将默认为未定义的
,就像任何其他不存在的属性一样。您如何定义“稀疏数组”以及如何在您的案例中创建一个?如果您这样做,var a=[];a[5]=42
,那么数组的长度当然是6
,但实际上它在索引5
处只有一个元素。您将看到,如果执行console.dir(a)
,那么似乎如果我们在空数组中设置一些元素,并且它们不是连续的,那么该数组就是稀疏数组。我使用console.log
和console.dir
转储了arr.map
和arr.collect
结果,它们看起来是一样的,所以看起来你有答案了。我尝试的稀疏数组是arr=[1,3,7,9,11]
那么这是否意味着array.map
实际上可以满足您的需要?您为什么将map
定义为一个简单的函数并使用this
?一个简单函数的this
表示全局范围……您可以在事后将其分配给对象或原型的属性。例如,Array.prototype.map=map代码>或变量a=[];a、 地图=地图
然后当您在a
上调用它时,“this”将具有正确的值。我本来可以写Array.prototype.map=函数映射…
,但我没有。啊哈,是的,我想知道你为什么要创建一个额外的函数,而不是仅仅分配给Array.prototype,因为它显然是在处理数组Array.prototype.map=map
可以完成,但是为什么要创建一个额外的悬空map
@動靜能量, 我没有什么特别的理由去创建一个全局函数,而不是仅仅分配给数组原型。然而,值得注意的是,ECMA声明“映射函数是有意泛型的;它不要求它的this
值是数组对象。”如果稀疏数组是[1,2,,,,,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,
,由于尾部稀疏性,如果要与原始数组相同,我认为结果数组的长度属性应该与映射对象的长度属性相同(或多或少)。