我想做的是创建一个递归版本的find,它接受一个数组和一个测试函数,并返回一个数组的第一个元素,它通过了测试。让我们看一下这个例子:
function isEven(num) { return(num%2 == 0); }
var arr = [1, 3, 5, 4, 2];
function findRecursive(arr, func) {
var p = arr.shift();
if (func(p) == true)
return p;
else
findRecursive(arr, func);
}
findRecursive(arr, isEven);
由于某种原因,我得到了不确定。但是如果我在第5行改变为弹出,它会正确返回2.导致这个问题的原因是什么?
答案 0 :(得分:2)
您需要返回递归调用的值,否则返回{J}中函数的标准return value undefined
。
} else {
return findRecursive(arr, func);
// ^^^
}
如果没有要检查的元素,您可以插入对数组长度的检查。然后你可以故意返回undefined
。
function isEven(num) { return num % 2 === 0; }
function findRight(array, fn) {
if (!array.length) {
return;
}
var p = array.pop();
return fn(p) ? p : findRight(array, fn);
}
console.log(findRight([1, 3, 5, 4, 2], isEven)); // 2
console.log(findRight([1, 3, 5], isEven)); // undefined

答案 1 :(得分:1)
递归是一种在函数式编程环境中诞生的循环机制;从它的上下文中取出它只能粗略地理解如何使用递归
递归,当与其他函数式编程实践(如持久性(不可变)数据类型和纯函数)一起使用时,可以作为纯表达式精美地表达
const find = (f, [x,...xs]) =>
x === undefined
? x
: f (x)
? x
: find (f, xs)
const isEven = x =>
(x & 1) === 0
console.log (find (isEven, [1, 3, 5, 4, 2])) // 4
console.log (find (isEven, [1, 3, 5, 7, 9])) // undefined
Be careful with recursion in JavaScript, tho - 使用堆栈安全循环机制来避免在大型阵列上吹掉堆栈
const recur = (...values) =>
({ type: recur, values })
const loop = f =>
{
let acc = f ()
while (acc && acc.type === recur)
acc = f (...acc.values)
return acc
}
const find = (f, xs) =>
loop ((i = 0) =>
i === xs.length
? undefined
: f (xs [i])
? xs [i]
: recur (i + 1))
const isEven = x =>
(x & 1) === 0
// [ 1, 2, 3, 4, ... 20000 ]
const numbers =
Array.from (Array (2e4), (x,n) => n + 1)
console.log (find (isEven, numbers)) // 2
// this would have blown the stack using the first version of `find`
// but it works just fine here, thanks to loop/recur
console.log (find (x => x < 0, numbers)) // undefined