如何在嵌套数组javascript中添加数字

时间:2016-02-26 05:48:05

标签: javascript logic

正在开展项目并尝试了一些不同的解决方案但没有结果。有人可以帮我解决如何在嵌套数组中添加数字的问题吗?我会用reduce吗?还是for循环?

function balance(arr) {
  if(typeof item == 'number') {
    return arr;enter code here
  } else {
    return arr + balance(item);
  }
}

4 个答案:

答案 0 :(得分:2)

这可能是你希望的吗?

function balance(arr) {
  return arr.reduce(function(sum, item) {
    if(typeof item == 'number') {
      return sum;
    } else {
      return sum + balance(item);
    }
  },0);
}

console.log(balance([1,2,[3,4],5]));

答案 1 :(得分:2)

只是为了记录(为了反驳需要递归的断言),这里是一个使用顺序算法的版本。递归简洁且(通常)更容易阅读,但如果速度很重要,它可能变慢。但是,基于jsPerf的结果,脚本引擎在优化递归代码方面似乎比以前更好,至少对于像这样的简单程序。

为了比较,我使用了一个普通循环包含了一个递归版本,jsPerf测试还包括一个使用 reduce 的(固定)递归版本。我怀疑Any的答案是最慢的,因为它在每个循环中调用slice和它本身,但我没有时间来修复它。

所以我觉得递归很好,因为它快速而简洁。

/*  Sum the values of nested arrays. Only checks if values are arrays,
**  otherwise assumes they're numbers
**
**  @param {Array} arr - array of numbers to process, may have 
**                       nested arrays of numbers
**  @returns {number} - sum of values or NaN if arr is not an Array
*/
function balance(arr) {
  
  // Only process arrays
  var isArray = Array.isArray;
  if (!isArray(arr)) return NaN;

  // Setup
  var arrays = [], indexes = [];
  var currentArray = arr;
  var currentValue;
  var sum = 0;
  var i = 0, iLen = arr.length;
  
  // Use <= length as must handle end of array inside loop
  while (i <= iLen || arrays.length) {
    currentValue = currentArray[i];

    // If at end of current array, reset value to before entering array
    // Reset i to previous value as will increment at the bottom
    if (i == currentArray.length && arrays.length) {
      currentArray = arrays.pop();
      i = indexes.pop();
      iLen = currentArray.length;

    // If current value is an array, use it and reset loop control values
    // set i to -1 as will increment at the bottom
    } else if (isArray(currentValue)) {
      arrays.push(currentArray);
      indexes.push(i);
      currentArray = currentValue;
      i = -1;
      iLen = currentArray.length;

    // Otherwise, add the current value
    // Will be undefined if at end of array so add zero
    } else {
      sum += +currentValue || 0;
    }
    
    // Increment i
    i++;
  }
  return sum;
}

document.write(
  'balance sequential 1: ' +
  balance([1,[2,1,[1,2,-1],[1]],1,[2,1]]) // 11
  + '<br>balance sequential 2: ' +
  balance([1,2,[3,4],5]) // 15
);


/*  Sum the values of nested arrays. Only checks if values are arrays,
**  otherwise assumes they're numbers
**
**  @param {Array} arr - array of numbers to process, may have 
**                       nested arrays of numbers
**  @returns {number} - sum of values or NaN if arr is not an Array
*/
function balanceLoop(arr) {
  if (!Array.isArray(arr)) return NaN;
  for (var value, total=0, i=0, iLen=arr.length; i<iLen; i++) {
    value = arr[i];
    total += Array.isArray(value)? balanceLoop(value) : value;
  }
  return total;
}

document.write(
  '<br>balanceLoop 1: ' +
  balanceLoop([1,[2,1,[1,2,-1],[1]],1,[2,1]]) // 11
  + '<br>balanceLoop 2: ' +
  balanceLoop([1,2,[3,4],5]) // 15
);

答案 2 :(得分:1)

一个简单的递归函数:

function balance(arr, total) {
  total = total || 0;
  if (arr.length === 0) return total;
  var head = arr[0];
  if (typeof head === 'number') {
    return balance(arr.slice(1), total += head);
  } else {
    return balance(head, total);
  }
}

balance([1, [2, 1, 3, [43, 2]]])); // 52

DEMO

答案 3 :(得分:0)

我可能会使用递归reduce来解决这个问题,方法如下:

{{1}}

如果你不介意开销,你当然可以这样做:

{{1}}