我正试图和我的伙伴一起玩,他解决了8m 7s中提到的问题,对我而言,它已经消失了20米。我无法弄清楚如何在javascript中处理无限制的嵌套数组。
问题在于:
// i will be an array, containing integers, strings and/or arrays like itself.
// Sum all the integers you find, anywhere in the nest of arrays.
所以
arraySum([[1,2,false],'4','5']) will return 3 (passed)
arraySum([[1,2,3],4,5]) will return 15 (passed)
arraySum([[[[[[[[[1]]]]]]]], 1]) will return 2 (failed)
我写的代码是:
function arraySum(i) {
sum = 0;
tmp =0;
for (var a=0; a<i.length; a++){
if (i[a] instanceof Array) {
ar = i[a];
for (var j=0; j<ar.length; j++){
tmp +=ar[j];
}
}
if (typeof i[a] == "number")
sum += i[a];
console.log(sum);
}
return sum + tmp;
}
正如你所看到的,它无法处理我失败的最后一种情况,因为我无法弄清楚如何在JS中处理无限的嵌套。
任何想法都会非常感激。 也试着在8m 7s之前完成它,我的好友完成了。
答案 0 :(得分:16)
在if (i[a] instanceof Array) {
部分内部,您必须使用递归来操作具有相同arraySum
函数的嵌套数组,而不仅仅是使用另一个循环。试试这个:
var arraySum = (function () {
"use strict";
var sumFunc, isArray;
sumFunc = function (arr) {
var sum, i, j, cur, toAdd;
sum = 0;
for (i = 0, j = arr.length; i < j; i++) {
cur = arr[i];
toAdd = 0;
if (isArray(cur)) {
toAdd = sumFunc(cur);
} else if (typeof cur === "number") {
toAdd = cur;
}
sum += toAdd;
}
return sum;
};
isArray = Array.isArray || function (obj) {
return Object.prototype.toString.call(obj) === "[object Array]";
};
return sumFunc;
}());
DEMO: http://jsfiddle.net/Q7JPM/1
该函数只循环遍历数组中的所有项,并返回内部找到的任何数字的总和。如果该项本身是一个数组,则调用arraySum
并传递该数组...将结果添加到总和中。如果它是一个数字,它只是将其加到总和上。
答案 1 :(得分:3)
你必须使用递归:
function arraySumRec(theArray)
{
var sum=0;
for (var i=0;i<theArray.length;i++)
{
if (theArray[i] instanceof Array)
{
sum=sum+arraySumRec(theArray[i]);
}
else
{
if (typeof(theArray[i])=="number")
{
sum=sum+theArray[i];
}
}
}
return sum;
}
花了我3分47秒(由于打字错误,哈哈)。
答案 2 :(得分:2)
Javascript Array reduce方法非常适合解决此类问题。 reduce方法接受一个至少有两个参数的函数:accumulator和数组的当前元素。在函数体中,指定每个元素应如何影响累加器。函数的第二个参数是累加器的起始值。
function sum(x) {
return x.reduce(function(accumulator, currentValue) {
if (typeof currentValue === "number") {
return accumulator + currentValue;
} else if (currentValue instanceof Array) {
return accumulator + sum(currentValue);
} else {
return accumulator;
}
}, 0);
}
函数sum采用数组,reduce方法将其减少为单个值。在“else if”分支中,我们找到一个嵌套数组,我们可以简单地在其上调用sum,获取单个值,并将其添加到我们的累加器中。在“else”分支中,我们没有找到我们感兴趣的值的类型,因此我们保持累加器不变。
documentation at MDN通过示例提供了对Array reduce的一个很好的解释。
答案 3 :(得分:2)
function arraySum(i) {
var l = i.length, sum = 0;
while (l--) {
if (typeof i[l] !== 'number' && !(i[l] instanceof Array)) continue;
if (i[l] instanceof Array) { sum += arraySum(i[l]); continue; }
sum += i[l];
}
return sum;
}
答案 4 :(得分:1)
使用堆栈进行非递归。
function arraySum(arr)
{
var sum = 0;
while(arr.length != 0)
{
var value = arr.pop();
if(value instanceof Array)
{
for (i= 0; i< value.length; ++i)
arr.push(value[i]);
}
else if(typeof value === "number")
sum += value;
}
return sum;
}
var arr = [1, 2, [3, 4, [[[5]]]]];
console.log(arraySum(arr));
答案 5 :(得分:0)
如果我们专注于正确的部分,我们可以避免将精力集中在错误的部分上-
function arraySum (t)
{ switch (t?.constructor)
{ case Array:
return t.reduce((r, v) => r + arraySum(v), 0)
case Number:
return t
default:
return 0
}
}
console.log(arraySum([[1,2,false],'4','5']))
console.log(arraySum([[1,2,3],4,5]))
console.log(arraySum([[[[[[[[[1]]]]]]]], 1]))
3
15
2
如果您的环境尚不支持?.
,则可以将其换出-
switch (t?.constructor)
switch (t && t.constructor) // <- where ?. is unsupported
编辑:我花了2769天来回答这个问题,但只花了几分钟就写出了:D