Yoa*_*sky 5 javascript variables recursion
这个函数是用 JavaScript 编写的,但我认为这个概念可以用其他一些编程语言来实现。
function uniteUnique(arr) {
let seenBefore = []; //the accumulating array
for (let item of arguments) {
if (typeof (item) == "object") {
uniteUnique(...item);
}
else if (!seenBefore.includes(item)) {
seenBefore.push(item);
}
}
return seenBefore;
}
Run Code Online (Sandbox Code Playgroud)
简而言之,该函数迭代它作为参数接收的数组,这些数组本身可能包含也可能不包含其他数组。这些数组的最深层都包含int值。该函数返回一个包含所有这些ints(即出现在嵌套数组中的那些)的数组,但它仅返回每个 int 一次,即使它出现多次。
我的问题在于,每次递归返回到更高级别时,它都会再次初始化包含保存的数组int,即函数需要返回的数组(seenBefore),因此破坏了整个过程。一方面,我必须在函数启动时初始化数组,但另一方面,它会被多次初始化并丢失以前存储的值。
例如,如果我要运行该函数
uniteUnique([1, 3, [6, 3], 2], [5, 2, 1, 4], [2, 1]);
输出应该是
[1,3,6,2,5,4]
因为该函数必须按照处理顺序仅返回一次偶然发现的数字。该函数实际上返回一个空数组,因为它在函数从递归的最顶层返回之前再次初始化。
我怎样才能绕过这个问题?
(PS:我知道这可以通过将累加数组从函数中拉出到不同的作用域来“解决”,但这会导致其他问题,例如如果我运行,则每次运行函数之前都需要重新初始化累加数组不止一次。)
小智 3
你错误地识别了你的问题。每次调用uniteUnique()都有一个单独的局部变量值seenBefore——在递归调用期间没有任何内容被“再次初始化”。
你真正的问题是这一行:
uniteUnique(...item);
Run Code Online (Sandbox Code Playgroud)
丢弃该函数调用的结果,因此任何嵌套数组的内容都将被忽略。您需要将该函数的返回值分配到某处并使用它。
您可能还想将此函数调用的条件更改为:
if (Array.isArray(item)) {
Run Code Online (Sandbox Code Playgroud)
因为当前条件typeof item == "object"将包括无法迭代的对象。