我正在尝试使用递归遍历一个简单的数组。对于此特定情况,我尝试使用递归方式重新创建.map()
(不使用.map()
!。目前,我只将原始数组中的最后一个元素推入,但我想将所有元素都推入数组
function recursiveMap (arr, func) {
let newArr = [];
if (arr.length === 1){
newArr.push(func(arr));
}
else {
newArr.push(...recursiveMap(arr.slice(1),func));
}
return newArr;
}
答案 0 :(得分:4)
您需要在当前项目上使用func
,并在数组的其余部分上扩展调用函数的结果:
function recursiveMap(arr, func) {
return arr.length ? [func(arr[0]), ...recursiveMap(arr.slice(1), func)] : [];
}
const arr = [1, 2, 3];
const result = recursiveMap(arr, n => n * 2);
console.log(result);
答案 1 :(得分:2)
您的基本情况似乎是错误的。您将需要检查一个空数组:
function recursiveMap (arr, func) {
let newArr = [];
if (arr.length === 0) {
// do nothing
} else {
newArr.push(func(arr[0]));
newArr.push(...recursiveMap(arr.slice(1),func));
}
return newArr;
}
相反,当至少有一个元素时,您需要调用func
(在第一项上)。
答案 2 :(得分:1)
通过递归,我发现使基本情况成为您检查函数的第一件事,并在那里缩短执行时间会很有帮助。 map的基本情况是数组有0个项目,在这种情况下,您将返回一个空数组。
如果在let [a, ...b]
进行数组解构之前没有看到它,则a成为第一个值,b保留剩余的数组。您可以对slice执行相同的操作。
function recursiveMap(arr, func){
if(arr.length == 0) return [];
let [first, ...rest] = arr;
return [func(first)].concat(recursiveMap(rest, func));
}
let test = [1,2,3,4,5,6,7];
console.log(recursiveMap(test, (item) => item * 2));
编辑
回到您的样本中,我很清楚地看到您在xD之前已经看到了销毁。不过,将其留在答案中供将来的读者阅读。
答案 3 :(得分:1)
以下是一些替代方案。每个recursiveMap
[]
时,解构任务
const identity = x =>
x
const recursiveMap = (f = identity, [ x, ...xs ]) =>
x === undefined
? []
: [ f (x), ...recursiveMap (f, xs) ]
const square = (x = 0) =>
x * x
console.log (recursiveMap (square, [ 1, 2, 3, 4, 5 ]))
// [ 1, 4, 9, 16, 25 ]
数组切片
const identity = x =>
x
const recursiveMap = (f = identity, xs = []) =>
xs.length === 0
? []
: [ f (xs[0]), ...recursiveMap (f, xs.slice (1)) ]
const square = (x = 0) =>
x * x
console.log (recursiveMap (square, [ 1, 2, 3, 4, 5 ]))
// [ 1, 4, 9, 16, 25 ]
具有默认分配的其他参数–创建较少的中间值
const identity = x =>
x
const recursiveMap = (f = identity, xs = [], i = 0) =>
i >= xs.length
? []
: [ f (xs[i]) ] .concat (recursiveMap (f, xs, i + 1))
const square = (x = 0) =>
x * x
console.log (recursiveMap (square, [ 1, 2, 3, 4, 5 ]))
// [ 1, 4, 9, 16, 25 ]
尾部递归(又可爱)
const identity = x =>
x
const prepend = x => xs =>
[ x ] .concat (xs)
const compose = (f, g) =>
x => f (g (x))
const recursiveMap = (f = identity, [ x, ...xs ], then = identity) =>
x === undefined
? then ([])
: recursiveMap
( f
, xs
, compose (then, prepend (f (x)))
)
const square = (x = 0) =>
x * x
console.log (recursiveMap (square, [ 1, 2, 3, 4, 5 ]))
// [ 1, 4, 9, 16, 25 ]
// => undefined
recursiveMap (square, [ 1, 2, 3, 4, 5 ], console.log)
// [ 1, 4, 9, 16, 25 ]
// => undefined
recursiveMap (square, [ 1, 2, 3, 4, 5 ])
// => [ 1, 4, 9, 16, 25 ]
源自尾递归foldl
–注意foldl
选择了上面使用的类似技术:具有默认赋值的其他参数。
const identity = x =>
x
const foldl = (f = identity, acc = null, xs = [], i = 0) =>
i >= xs.length
? acc
: foldl
( f
, f (acc, xs[i])
, xs
, i + 1
)
const recursiveMap = (f = identity, xs = []) =>
foldl
( (acc, x) => acc .concat ([ f (x) ])
, []
, xs
)
const square = (x = 0) =>
x * x
console.log (recursiveMap (square, [ 1, 2, 3, 4, 5 ]))
// [ 1, 4, 9, 16, 25 ]
答案 4 :(得分:0)
欢迎堆栈溢出。您可以像以下示例一样将结果传递给自身:
function recursiveMap (arr, func,result=[]) {
if (arr.length === 0){
return result;
}
return recursiveMap(
arr.slice(1),
func,
result.concat([func(arr[0])])
);
}
console.log(recursiveMap([1,2,3,4],x=>(x===3)?['hello','world']:x+2));
或在函数中定义递归函数:
function recursiveMap (arr, func) {
const recur = (arr, func,result=[])=>
(arr.length === 0)
? result
: recur(
arr.slice(1),
func,
result.concat([func(arr[0])])
);
return recur(arr,func,[])
}
console.log(recursiveMap([1,2,3,4],x=>(x===3)?['hello','world']:x+2));
答案 5 :(得分:0)
您可以通过使用第三个参数作为收集的值来采用另一种方法。
function recursiveMap(array, fn, result = []) {
if (!array.length) {
return result;
}
result.push(fn(array[0]));
return recursiveMap(array.slice(1), fn, result);
}
console.log(recursiveMap([1, 2, 3, 4, 5], x => x << 1));
console.log(recursiveMap([], x => x << 1));
答案 6 :(得分:-2)
添加newArr.push(func(arr[0]));
,然后再次调用该函数
function recursiveMap (arr, func) {
let newArr = [];
if (arr.length === 1){
newArr.push(func(arr));
}
else {
newArr.push(func(arr[0]));
newArr.push(...recursiveMap(arr.slice(1),func));
}
return newArr;
}
console.log(recursiveMap([1,2,3], function(a){return +a+2}))
相同但经过修改的答案,已纠正错误
function recursiveMap (arr, func) {
let newArr = [];
if(arr.length){
newArr.push(func(arr[0]));
if(arr.length > 1){
newArr.push(...recursiveMap(arr.slice(1),func));
}
}
return newArr;
}
console.log(recursiveMap([1,2,3], function(a){return a+2}))