【问题标题】:Adding numeric values in a string together将字符串中的数值相加
【发布时间】:2020-12-15 15:46:25
【问题描述】:

我有一个从端点返回的字符串,我需要将字符串的某些部分添加在一起以产生两个不同的值。

示例响应:

149,226;147,226;146,224

现在我知道我可以使用一元加号运算符来强制将字符串视为这样的数字。

var num1 = '20',
    num2 = '22';

var total = (+num1) + (+num2);

或者我可以像这样进行一些转换

   var number1 = parseInt(num1);
   var number2 = parseInt(num2);

   var total = number1  + number2;

其中任何一个都可以正常工作,但这并不是我想要的。

我想得到这个结果

149,226;147,226;146,224

然后将第一个来者之前的所有数字加在一起,这样将是 (149, 147, 146) 以产生一个结果,然后将第二个来者之后的所有数字加在一起 ​​(226, 226, 224)。

我知道我可能需要某种 reg 表达式,我只是不知道是什么。

【问题讨论】:

    标签: javascript regex string


    【解决方案1】:

    你可以使用 string.split,两次,一次用于 ;然后再为 ,。并将其放入 array.reduce。

    例如。

    var str = '149,226;147,226;146,224';
    
    
    var result = str.split(';')
      .reduce((a,v) => {
        var vv = v.split(',');
        a[0] += vv[0] | 0;
        a[1] += vv[1] | 0;
        return a;
      }, [0, 0]);
      
    console.log(result);

    对于更通用的解决方案,可以处理任意数量的子字符串,例如。 1,2,3;4,5,6,还可以处理其他拆分类型,并应对额外的,;

    function sumStrings(str, outerSplit, innerSplit) {
      return str.split(outerSplit || ';')
        .filter(Boolean)
        .reduce((a,v) => {
          v.split(innerSplit || ',')
            .filter(Boolean)
            .forEach((v,ix) => {
              a[ix] = (a[ix] | 0) + (v | 0);
            });
          return a;
        }, []);      
    }
    
    console.log(sumStrings(
      '149,226;147,226;146,224'
    ));
      
    console.log(sumStrings(
      '149.226.201|147.226.112.|146.224.300|',
      '|','.'));
      
    //how about total of totals?
    console.log(sumStrings(
      '149,226;147,226;146,224'
    ).reduce((a,v) => a + v));
    .as-console-wrapper {
      min-height: 100%
    }

    【讨论】:

    • 如果逗号之间有两个以上的数字怎么办?
    • @ritaj 更新为包含更通用的解决方案。
    【解决方案2】:

    你可以这样做:

    const myString = '149,226;147,226;146,224';
    
    /*
     * 1. you split the string by ';' to obtain an array of string couples
     *    then you split each couple by ','. In this way you end up with an array like this:
     *    [['149', '266'], ['147', '266'], ['146', '264']]
     */
    const myNumbers = myString.split(';').map(numCouple => numCouple.split(','));
    
    /*
     * 2. you use Array.prototype.reduce() to calculate the sums
     */
    const sum1 = myNumbers.reduce((sum, item) => {
      return sum += parseInt(item[0]);
    }, 0);
    const sum2 = myNumbers.reduce((sum, item) => {
      return sum += parseInt(item[1]);
    }, 0);
    
    // or, as an alternative:
    const sumsObj = myNumbers.reduce((obj, item) => {
      obj.sum1 += parseInt(item[0]);
      obj.sum2 += parseInt(item[1]);
      return obj;
    }, { sum1: 0, sum2: 0 });
    
    // or also:
    const sumsArr = myNumbers.reduce((acc, item) => {
      acc[0] += parseInt(item[0]);
      acc[1] += parseInt(item[1]);
      return acc;
    }, [0, 0]);
    
    
    // test
    console.log('sum1:', sum1);
    console.log('sum2:', sum2);
    console.log('--------------');
    console.log('sum1:', sumsObj.sum1);
    console.log('sum2:', sumsObj.sum2);
    console.log('--------------');
    console.log('sum1:', sumsArr[0]);
    console.log('sum2:', sumsArr[1]);

    【讨论】:

      【解决方案3】:

      不使用正则表达式,一种可能的解决方案:

      var c = '149,226;147,226;146,224'
      var d = c.split(";")
      var first = d.map(x=>Number(x.split(",")[0]))
      var second= d.map(x=>Number(x.split(",")[1]))
      console.log(first)
      console.log(second)
      
      let resultFirst = first.reduce((a,b) => a + b, 0);
      let resultSecond = second.reduce((a,b) => a + b, 0);
      console.log(resultFirst)
      console.log(resultSecond)

      【讨论】:

      • 这是一个很好的简单答案,但您的 firstsecond 是数组。总结一下,最好补充一下:let resultFirst = first.reduce((a,b) => a + b, 0);let resultSecond = second.reduce((a,b) => a + b, 0);
      • 谢谢,已编辑答案以包含您的建议。
      • 虽然在分割结果时你会得到这个数组 ["146,224", "144,225", ""]。因此,您将在数组中获得一个空项目。我想您每次都可以使用 splice 清除最后一项。
      • 通常你应该得到第一个 [149,147,146] 和第二个 [226,226,224]。我编辑了帖子。运行代码sn -p就可以看到了。
      • 对不起,这是我的错,响应也以 ; 结尾例如'149,226;147,226;146,224;'
      【解决方案4】:

      下面将正则表达式提供给 String 的 .split 以自行获取数字。然后你可以添加所有其他数字,但我不明白为什么不按顺序添加它们。

      const str = '149,226;147,226;146,224'
      
      const total = str.split(/[;,]/).map(Number).reduce((a, b) => a + b)
      
      console.log('total', total)

      【讨论】:

        【解决方案5】:

        我运行了这个:

        const nums = ('149,226;147,226;146,224');
        var firstNums = nums.match(/(?<=[0-9]*)[0-9]+(?=,)/gs);
        var secondNums = nums.match(/(?<=[0-9]*)[0-9]+(?=;|$)/gs);
        console.log(firstNums, secondNums);
        let sumFirstNums = 0,  
            sumSecondNums = 0;
        firstNums.map(x => {
          sumFirstNums += +x;
        })
        console.log(sumFirstNums)
        
        secondNums.map(x => {
          sumSecondNums += +x;
        })
        console.log(sumSecondNums)
        
        //If you want the result in the same format: 
        const finalResult = `${sumFirstNums}, ${sumSecondNums};`
        console.log(finalResult)
        

        ;)

        【讨论】:

          【解决方案6】:

          对于该字符串格式,您可以使用具有 2 个捕获组的单一模式,匹配逗号之间的 1+ 个数字,并断言 ; 或右侧字符串的结尾。

          您通过索引到每次迭代的match 来引用组值。

          (\d+),(\d+)(?=;|$)
          

          模式匹配

          • (\d+)捕获组1,匹配1+位数
          • , 匹配逗号
          • (\d+)捕获组2,匹配1+位数
          • (?=;|$) 正向前瞻,直接向右断言 ; 或字符串结尾

          查看regex demo

          let result1 = 0;
          let result2 = 0
          
          for (const match of "149,226;147,226;146,224".matchAll(/(\d+),(\d+)(?=;|$)/g)) {
            result1 += +match[1]
            result2 += +match[2]
          }
          
          console.log(result1, result2);

          【讨论】:

            猜你喜欢
            • 2019-08-12
            • 1970-01-01
            • 1970-01-01
            • 2014-08-29
            • 2014-05-15
            • 1970-01-01
            • 1970-01-01
            • 2020-06-26
            • 1970-01-01
            相关资源
            最近更新 更多