Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/398.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript-在递归过程中可以使用.shift()更改数组吗?_Javascript_Arrays_Recursion - Fatal编程技术网

Javascript-在递归过程中可以使用.shift()更改数组吗?

Javascript-在递归过程中可以使用.shift()更改数组吗?,javascript,arrays,recursion,Javascript,Arrays,Recursion,我编写了一个递归函数来确定数组是否包含需要添加的元素,并形成一个目标数。但是,在执行此操作时,我在尝试使用.shift()删除数组中的第一个元素时遇到错误(第8行): 当我意识到collection.shift()是个问题时,我尝试将数组更改为collection.slice(1),程序现在可以运行了。即使现在,我也不明白为什么.shift()没有应用期望的结果。有人知道为什么吗?因为shift()修改了原始的集合对象,所以当findCombo(collection,target)方法在find

我编写了一个递归函数来确定数组是否包含需要添加的元素,并形成一个目标数。但是,在执行此操作时,我在尝试使用.shift()删除数组中的第一个元素时遇到错误(第8行):

当我意识到collection.shift()是个问题时,我尝试将数组更改为collection.slice(1),程序现在可以运行了。即使现在,我也不明白为什么.shift()没有应用期望的结果。有人知道为什么吗?

因为
shift()
修改了原始的集合对象,所以当
findCombo(collection,target)
方法在
findCombo(collection,target-next)
之后执行时,集合对象将为空

函数findCombo(集合,目标){
snippet.log(目标+':'+集合)
如果(目标===0){
返回true;
}else if(collection.length==0){
返回false;
}否则{
var next=集合[0];
collection.shift();//**不起作用**
//collection=collection.slice(1);//**有效**
返回findCombo(集合,目标-下一步)| | findCombo(集合,目标);
}
}
log(findCombo([1,2,3,4,5,20])

因为
shift()
修改了原始集合对象,所以当
findCombo(集合,目标)
方法在
findCombo(集合,目标-下一步)
之后执行时,集合对象将为空

函数findCombo(集合,目标){
snippet.log(目标+':'+集合)
如果(目标===0){
返回true;
}else if(collection.length==0){
返回false;
}否则{
var next=集合[0];
collection.shift();//**不起作用**
//collection=collection.slice(1);//**有效**
返回findCombo(集合,目标-下一步)| | findCombo(集合,目标);
}
}
log(findCombo([1,2,3,4,5,20])

问题在于,您只有一个
集合
数组,该数组由所有对
findCombo
的调用共享,并且
shift
会对该数组进行变异。这意味着当第一个递归调用
findCombo(collection,target-next)
清空数组时,第二个递归调用
findCombo(collection,target)
将发现(非常相同的)数组为空,尽管调用方并不打算这样做。通过使用
切片
,该函数不会损害提供给它的数组

通过在递归调用后将数组恢复为其原始值,可以避免此问题:

var next = collection[0];
collection.shift();
var res = findCombo(collection, target - next) || findCombo(collection, target);
collection.unshift(next);
return res;
但这有点难看。更好的方法是为下一个要尝试的位置使用一个额外的索引参数,而不是改变或克隆数组:

var next = collection[try];
return findCombo(collection, target - next, try+1) || findCombo(collection, target, try+1);

问题是您只有一个
集合
数组,所有对
findCombo
的调用都共享该数组,而
shift
会对该数组进行变异。这意味着当第一个递归调用
findCombo(collection,target-next)
清空数组时,第二个递归调用
findCombo(collection,target)
将发现(非常相同的)数组为空,尽管调用方并不打算这样做。通过使用
切片
,该函数不会损害提供给它的数组

通过在递归调用后将数组恢复为其原始值,可以避免此问题:

var next = collection[0];
collection.shift();
var res = findCombo(collection, target - next) || findCombo(collection, target);
collection.unshift(next);
return res;
但这有点难看。更好的方法是为下一个要尝试的位置使用一个额外的索引参数,而不是改变或克隆数组:

var next = collection[try];
return findCombo(collection, target - next, try+1) || findCombo(collection, target, try+1);

谢谢你的回复!虽然我也有类似的怀疑,但当时我很困惑,为什么将原始集合变量的值重新分配给collection.slice(1)不会产生同样的错误。感谢您的回复!虽然我也有类似的怀疑,但当时我很困惑,为什么将原始集合变量的值重新分配给collection.slice(1)不会产生同样的错误。让这类操作更容易的一个简单方法是使用Facebooks Immutable.js:@JustGage:的确如此。尽管有人可能会说,
.slice(1)
已经足够简单了(只是性能没有那么好):-)让这类操作更简单的一个简单方法是使用facebook Immutable.js:@JustGage:的确如此。尽管有人可能会争辩说,
.slice(1)
已经足够简单了(只是性能没有那么好):-)