我正在尝试构建一个将字符串中的所有数字相加的函数...例如,'dlsjf3diw62'最终会为65.
我试图变得聪明并将一个递归函数放在一起:
function NumberAddition(str) {
var numbers='1234567890';
var check=[];
str=str.split[''];
function recursive(str,check) {
if (str.length==0)
return check;
else if (numbers.indexOf(str[0])>=0)
{
for (i=0;i<str.length;i++){
if (numbers.indexOf(str[i])<0)
check.push(str.slice(0,i));
str=str.slice(i);
return recursive(str,check);
}
}
else
str.shift();
return recursive(str,check);
}
你会看到我正在尝试将我的数字作为名为check的数组中的数组返回。不幸的是,我超出了最大调用堆栈大小,我不知道为什么!递归确实有一个基本情况!它结束一旦str不再有任何内容。为什么这不起作用?有什么我想念的吗?
- 将会
答案 0 :(得分:2)
使用正则表达式,您可以使用更简单的解决方案实现相同的目的,如下所示:
var str = 'dlsjf3diw62';
var check = str.match(/\d+/g); // this pattern matches all instances of 1 or more digits
然后,要对数字求和,您可以这样做:
var checkSum = 0;
for (var i = 0; i < check.length; i++) {
checkSum += parseInt(check[i]);
}
或者,更紧凑:
var checkSum = check.reduce(function(sum, num){ return sum + parseInt(num) }, 0);
答案 1 :(得分:1)
你的递归不起作用的原因是你输入for
循环,因为你找到了一个数字,但数字仍然是字符串的结尾。如果发生这种情况,return
循环内的for
永远不会发生,循环结束。之后,.shift()
会发生不,因为它位于else
分支中,因此您将返回重新处理相同的字符串。
您不应该以这种方式解决这个特定问题,但代码是return
内部if
语句后跟else
语句的反模式的一个很好的例子。如果它看起来像这样,你的代码会更清晰(并且可以工作):
function recursive(str, check) {
if (str.length == 0)
return check;
if (numbers.indexOf(str[0]) >= 0) {
// Find the end of the string of digits, or
// the end of the whole thing
for (var i = 0; i < str.length && numbers.indexOf(str[i]) >= 0; i++);
check.push(str.slice(0, i));
str = str.slice(i);
return recursive(str, check);
}
// A non-digit character
str.shift();
return recursive(str, check);
}
在该版本中,没有else
个子句,因为两个if
子句总是涉及return
。 for
循环更改为查找后续切片的正确值“i”。
编辑 - 有一点不能解决的问题是您将数组推入“检查”列表。也就是说,子串“62”将被推送为数组["6", "2"]
。这不是一个大问题;它通过在正确的位置添加.join()
来解决。