我正在练习更高阶的功能,实际上是对引擎盖下的内容进行硬编码。我对这些问题感到困惑,因为我对apply()和arguments的工作原理知之甚少。
这是我的预期结果:
mapN([1, 2, 3], [4, 5, 6], [2, 2, 2], function(a, b, c) {
return (a * b) + c;
});
// => [6, 12, 20]
mapN([1, 2, 3], function(x) { return x * x; }) // => [1, 4, 9]
我手动编写了一个forEach函数和一个这样的Map函数(我知道这不是必要的,但我试图真正了解HOF引擎盖下的内容):
function each(coll, f) {
if (Array.isArray(coll)) {
for (var i = 0; i < coll.length; i++) {
f(coll[i], i);
}
} else {
for (var key in coll) {
f(coll[key], key);
}
}
}
function map(array, f) {
var acc = [];
each(array, function(element, i) {
acc.push(f(element, i));
});
return acc;
}
但是,我不知道从哪里开始。我如何一起使用apply和arguments?我花了一个小时试图搞清楚吗? :
function mapN(f){
var newArray = [];
var args = Array.prototype.slice.apply(arguments);
f.apply(newArray, args)
return newArray;
}
答案 0 :(得分:1)
您应遍历所有数组以生成将用于apply
的参数数组:
function mapN () {
var args = Array.from(arguments), // arguments passed to `mapN`
callback = args.pop(), // the callback function is the last argument
result = []; // the result array
if(!args.length) return result; // if there is no arrays passed as arguments, then return the empty array
for(var i = 0, len = args[0].length; i < len; i++) { // for each i from 0 to the length of one of the arrays
var params = args.map(arr => arr[i]); // get the i-th element of every array in args to use as parameters to the callback
result.push(callback.apply(null, params)); // call the callback with the params array and store the result
}
return result;
}
注意:如果数组的长度不同,那么您可能想要更改:
len = args[0].length
为:
len = Math.max.apply(null, args.map(arr => arr.length));
所以len
将等于可能的最大长度。
<强>示例:强>
function mapN () {
var args = Array.from(arguments),
callback = args.pop(),
result = [];
if(!args.length) return result;
for(var i = 0, len = args[0].length; i < len; i++) {
var params = args.map(arr => arr[i]);
result.push(callback.apply(null, params));
}
return result;
}
var a = mapN([1, 2, 3], [4, 5, 6], [2, 2, 2], function(a, b, c) {
return (a * b) + c;
});
console.log(a);
// => [6, 12, 20]
var b = mapN([1, 2, 3], function(x) { return x * x; });
console.log(b);
// => [1, 4, 9]