返回参数中传递的所有数字之和的函数

时间:2017-07-26 19:38:03

标签: javascript arrays filter sum arguments

我需要帮助。你能帮我解决一下这个任务吗?

  

编写返回所有数字的总和的函数,甚至是作为参数传递的字符串数字,这些数字的数量是无限的。   如果其中一个参数是一个数组,那么   Sum也被添加到该数组的值的总和(如果有的话)   此数组的值也是一个数组,然后添加结果   也是其值的总和,等等。

var sum = getSum (1, '1', 'one', [2, '2', 'two']);
console.log(sum);

我试着写这样的东西:

function getSum(){
    var separeted = string.split(",");
    var sum =0; 
    for(var i=0;i<arguments.length;i++){

        sum += parseInt(arguments[i].toString()..match(/(\d+)/));

    }
   return sum;
}
var sum = getSum(1,"1","one",[2,'2', 'two']);
console.log(sum);

在这里我已经堆积了。我认为我将需要拆分和过滤,但如何将所有这些组合在一个我找不到的功能中。 感谢。

3 个答案:

答案 0 :(得分:2)

您可以定义一个递归函数,如下所示:

function getSum () {
  return Array.from(arguments).reduce((sum, value) => {
    if (Array.isArray(value)) {
      sum += getSum.apply(this, value)
    } else {
      sum += Number(value)
    }

    return sum
  }, 0)
}

var sum = getSum (1, '1', '3', [2, '2', '10']);

console.log(sum);

为了计算字符串编号,您必须定义从单词到数字的映射,并迭代遍历单词字符串以生成数字。这是一个可能的实现:

var stringToNumber = (function () {
  const primary = new Map([
    ['zero', 0],
    ['one', 1],
    ['two', 2],
    ['three', 3],
    ['four', 4],
    ['five', 5],
    ['six', 6],
    ['seven', 7],
    ['eight', 8],
    ['nine', 9]
  ])
  
  const secondary = new Map([
    ['ten', 10],
    ['eleven', 11],
    ['twelve', 12],
    ['thirteen', 13],
    ['fourteen', 14],
    ['fifteen', 15],
    ['sixteen', 16],
    ['seventeen', 17],
    ['eighteen', 18],
    ['nineteen', 19]
  ])
  
  const prefix = new Map([
    ['twenty', 20],
    ['thirty', 30],
    ['forty', 40],
    ['fifty', 50],
    ['sixty', 60],
    ['seventy', 70],
    ['eighty', 80],
    ['ninety', 90]
  ])

  const magnitude = new Map([
    ['hundred', 1e2],
    ['thousand', 1e3],
    ['million', 1e6],
    ['billion', 1e9],
    ['trillion', 1e12],
    ['quadrillion', 1e15],
    ['quintillion', 1e18],
    ['sextillion', 1e21],
    ['septillion', 1e24],
    ['octillion', 1e27],
    ['nonillion', 1e30],
    ['decillion', 1e33]
  ])
  
  const types = { primary, secondary, prefix, magnitude }

  class Parser {
    static parse(word) {
      if (isNaN(word)) {
        const [type = null] = Object.keys(types)
          .filter(type => types[type].has(word))
        const value = types[type] ? types[type].get(word) : NaN
        
        return { type, sign: 1, value }
      } else {
        const value = Math.abs(word)
        const sign = Math.sign(word)
        const [type = 'primary'] = Object.keys(types)
          .filter(type => Array.from(types[type].values()).includes(value))

        return { type, sign, value }
      }
    }

    constructor() {
      this.words = []
    }
    
    push(word) {
      const parsed = Parser.parse(word)
      
      if (parsed.type === null) {
        return this.words.length
      }
      
      return this.words.push(parsed)
    }
    
    valueOf() {
      if (this.words.length === 0) {
        return NaN
      }
      
      const words = this.words

      let total = 0
      let { type: lastType, sign, value: run } = words[0]
      let maxMagnitude = lastType === 'magnitude' ? run : 1
      
      for (const { type, value } of words.slice(1)) {
        switch (type) {
          case 'magnitude':
            if (value > maxMagnitude) {
              run = (total + run) * value
              total = 0
              maxMagnitude = value
            } else {
              run *= value
            }
            break
          case 'secondary':
          case 'prefix':
            switch (lastType) {
              case 'magnitude':
                total += run
                run = value
                break
              case 'primary':
              case 'secondary':
              case 'prefix':
                run = Number(String(run) + String(value))
            }
            break
          case 'primary':
            switch (lastType) {
              case 'magnitude':
                total += run
                run = value
                break
              case 'prefix':
                run += value
                break
              case 'primary':
              case 'secondary':
                run = Number(String(run) + String(value))
            }
        }
        
        lastType = type
      }
      
      return sign * (total + run)
    }
  }

  return function stringToNumber (string) {
    const words = string
      .trim()
      .toLowerCase()
      .split(/\s+/g)

    const parser = new Parser()
    
    for (const word of words) {
      parser.push(word)
    }
    
    return parser.valueOf()
  }
})()

function getSum () {
  return Array.from(arguments).reduce((sum, value) => {
    if (Array.isArray(value)) {
      sum += getSum.apply(this, value)
    } else if (!isNaN(value)) {
      sum += Number(value)
    } else {
      sum += stringToNumber(String(value))
    }

    return sum
  }, 0)
}

var sum = getSum (1, '1', 'one hundred thousand', [2, '2', 'twenty six hundred']);

console.log(sum);

答案 1 :(得分:0)

感谢大家,我在David Flanagan的旧版&#34; reilly Javascript中找到了解决方案&#34;

所以我想在循环中我必须检查它是否为空而不是将元素更改为Number() 这是书中的代码

function flexisum(a) {
    var total = 0;
    for(var i = 0; i < arguments.length; i++) {
        var element = arguments[i], n;
        if (element == null) continue; // Ignore null & undefined
        if (isArray(element))          // if argument is array
            n = flexisum.apply(this, element);  // count sum of all elements
        else if (typeof element === "function") // if it's a function
            n = Number(element());              // call and convert it to the 'number'
        else n = Number(element);      // or to convert it anyway
        if (isNaN(n)) // If it was not possible to convert to a number, initiate exc.
            throw Error("flexisum(): can't convert " + element +
                        "into the number");
        total += n;   // Otherwise, add n to the total
    }
    return total;
}

但在我的情况下,我已根据自己的需要对其进行了检查,并将其删除了。所以它可以在没有字符串的情况下计算总和。

if (isNaN(n)) continue;
  total += n;

}

所以,感谢大家。 书籍是好的主题))))

答案 2 :(得分:-2)

我认为需要迭代任意数量的标签,因此您可以使用以下方法

   function jsArrSum(arr) {
      var sum = 0;
      for (var i = 0; i < arr.length; i++) {
        if (typeof arr[i] == 'object')
          sum += jsArrSum(arr[i]);
        else
          sum += arr[i];
      }
      return sum;
    }

    jsArrSum(array);