2

I am trying to have fun with my buddy who solved the problem mentioned in 8m 7s, and for me it is already 20m gone. I can't figure out how to handle unlimited nested array in javascript.

The problem is this:

// 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.

So

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)

The code I wrote is:

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;

}

As you can see it does not handle the last situation that I failed as I can't figure out how to handle unlimited nest in JS.

Any idea will be much appreciated. Also try to finish it before 8m 7s, which my buddy finished in.

4

6 に答える 6

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;
}());

デモ: http://jsfiddle.net/Q7JPM/1

この関数は、配列内のすべての項目をループし、内部で見つかった数値の合計を返します。アイテムが配列自体の場合、arraySumその配列を呼び出して渡します...結果を合計に追加します。数値の場合は、単純に合計に加算されます。

于 2013-10-04T14:38:04.850 に答える
4

再帰を使用する必要があります:

http://jsfiddle.net/HMnat/2

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秒かかりました(タイプミスのため、ハハ)。

于 2013-10-04T14:46:22.417 に答える
2

Javascript Array reduce メソッドは、この種の問題を解決するのに最適です。reduce メソッドは、アキュムレータと配列の現在の要素の少なくとも 2 つの引数を持つ関数を取ります。関数の本体で、各要素がアキュムレータに与える影響を指定します。関数の 2 番目の引数は、アキュムレータの開始値です。

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);
}

JSFIDDLE

関数 sum は配列を取り、reduce メソッドはそれを 1 つの値に減らします。ネストされた配列を見つける "else if" ブランチでは、単純にその配列に対して sum を呼び出し、単一の値を取得して、それをアキュムレータに追加することができます。「else」ブランチでは、関心のある種類の値が見つからないため、アキュムレータを変更せずに残します。

MDNのドキュメントには、例を含む Array reduce の適切な説明が記載されています。

于 2013-10-04T15:20:02.703 に答える
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));
于 2015-02-23T22:54:57.680 に答える