如何在不同的行字符串中添加值?

时间:2019-06-17 18:27:05

标签: javascript

我有一些包含多行的数据,如下所示。我需要将每个字符串中的值加起来。

原始字符串:

/dev/mapper/mpathap1  10M  141M  311M  32% /boot
udev/mapper/sysvg-optlv 976M  2.3M  923M   1% /home
/dev/mapper/sysvg-homelv
                      10M  2.3M  923M   1% /home
nfs/mapper/sysvg-optlv
                      10M  2.3M  923M   1% /home
udev/mapper/sysvg-optlv
                      976M  2.3M  923M   1% /home
/dev/mapper/mpathap1  10M  141M  311M  32% /boot

我需要的价值计算:

  1. 我应该能够阅读每一行并最终加起来'10M'的展示位置值
  2. 我应该能够跳过以'nfs','udev'开头的任何行
  3. 3-4、5-6、7-8行应该在同一行中,但是由于字符串长度为4、6、8行,所以换成了新行。

我尝试了以下代码,但是由于所有内容都在同一行中,因此我只能捕获单行(例如第一行和最后一行)中的值。

let lines = '/dev/mapper/mpathap1  10M  141M  311M  32% /boot
udev/mapper/sysvg-optlv 976M  2.3M  923M   1% /home
/dev/mapper/sysvg-homelv
                      10M  2.3M  923M   1% /home
nfs/mapper/sysvg-optlv
                      10M  2.3M  923M   1% /home
udev/mapper/sysvg-optlv
                      976M  2.3M  923M   1% /home
/dev/mapper/mpathap1  10M  141M  311M  32% /boot
let gb = 0;
let mb = 0;
for (var i = 0; i < lines.length; i++) {
        var disk = lines[i];
    if (!disk.startsWith('udev') && !disk.startsWith('nfs')){
            var diskSpace = disk.split(/\s+/).slice(1,2).toString();

            if(diskSpace.indexOf('G')> -1){
                gb = gb + parseInt(diskSpace);

            }if(diskSpace.indexOf('M')> -1){
                mb = mb + parseInt(diskSpace) / 1024;

            }
        }
    }
    console.log(gb  + mb);

答案为:30

5 个答案:

答案 0 :(得分:3)

我将使用数组方法(filtermapreduce)将过程的每个步骤链接起来,这样您就可以获得一种实用的方法:

let lines = `/dev/mapper/mpathap1  10M  141M  311M  32% /boot
udev/mapper/sysvg-optlv 976M  2.3M  923M   1% /home
/dev/mapper/sysvg-homelv
                      10M  2.3M  923M   1% /home
nfs/mapper/sysvg-optlv
                      10M  2.3M  923M   1% /home
udev/mapper/sysvg-optlv
                      976M  2.3M  923M   1% /home
/dev/mapper/mpathap1  10M  141M  311M  32% /boot`;

let sum = 
    // split into lines, keeping broken parts together
    lines.split(/\n(?=\S)/)
    // exclude lines with certain prefixes
    .filter(line => !line.startsWith("nfs/") && !line.startsWith("udev/"))
    // extract the numbers and their unit of measure
    .map(line => line.match(/\s\d+[MG]/))
    // convert to numbers in Megabytes
    .map(([str]) => parseInt(str) * (str.endsWith("G") ? 1024 : 1))
    // sum up
    .reduce((a, b) => a+b, 0);
    
console.log(sum);

如果您不支持ES6的箭头语法,则可以使用较早的语法:

var lines = "/dev/mapper/mpathap1  10M  141M  311M  32% /boot\n" +
    "udev/mapper/sysvg-optlv 976M  2.3M  923M   1% /home\n" +
    "/dev/mapper/sysvg-homelv\n" + 
    "                      10M  2.3M  923M   1% /home\n" + 
    "nfs/mapper/sysvg-optlv\n" + 
    "                      10M  2.3M  923M   1% /home\n" + 
    "udev/mapper/sysvg-optlv\n" + 
    "                      976M  2.3M  923M   1% /home\n" + 
    "/dev/mapper/mpathap1  10M  141M  311M  32% /boot";

var sum = 
    // split into lines, keeping broken parts together
    lines.split(/\n(?=\S)/)
    // exclude lines with certain prefixes
    .filter(function (line) {
         return line.indexOf("nfs/") !== 0 && line.indexOf("udev/") !== 0;
    })
    // extract the numbers and their unit of measure
    .map(function (line) {
         return line.match(/\s\d+[MG]/);
    })
    // convert to numbers in Megabytes
    .map(function (arr) {
         return parseInt(arr[0]) * (arr[0].slice(-1) === "G" ? 1024 : 1);
    })
    // sum up
    .reduce(function (a, b) {
         return a+b;
    }, 0);
    
console.log(sum);

答案 1 :(得分:1)

一些事情,首先是由于随机间距。我只是删除了该行以创建一致的行。如果您想将来重用它,我为REPLACEALL添加了一个可重用的函数。然后,我简单地拆分\n。另外,为进行添加,我必须在添加值之前先删除GM

String.prototype.replaceAll = function (find, replace) {
    var str = this;
    return str.replace(new RegExp(find.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), 'g'), replace);
};

let lines = `/dev/mapper/mpathap1  10M  141M  311M  32% /boot
udev/mapper/sysvg-optlv 976M  2.3M  923M   1% /home
/dev/mapper/sysvg-homelv
                      10M  2.3M  923M   1% /home
nfs/mapper/sysvg-optlv
                      10M  2.3M  923M   1% /home
udev/mapper/sysvg-optlv
                      976M  2.3M  923M   1% /home
/dev/mapper/mpathap1  10M  141M  311M  32% /boot`;

lines = lines.replaceAll("\n                      ","  ").split("\n");

var gb = 0;mb = 0;
for (var i = 0; i < lines.length; i++) {
        var disk = lines[i];
    if (!disk.startsWith('udev') && !disk.startsWith('nfs')){
            var diskSpace = disk.split(/\s+/).slice(1,2).toString();

            if(diskSpace.indexOf('G')> -1){
                diskSpace = diskSpace.replace("G","");
                gb = gb + parseInt(diskSpace);

            }if(diskSpace.indexOf('M')> -1){
                diskSpace = diskSpace.replace("M","");
                mb = mb + parseInt(diskSpace) / 1024;

            }
        }
    }
    console.log(gb,mb);

答案 2 :(得分:1)

您可以使用split(\n)将此字符串分成几行,合并换行,然后过滤掉以nfsudev开头的所有行。

如果只有相关行,请使用reduce来累积值。

const str = `/dev/mapper/mpathap1  10M  141M  311M  32% /boot
udev/mapper/sysvg-optlv 976M  2.3M  923M   1% /home
/dev/mapper/sysvg-homelv
                      10M  2.3M  923M   1% /home
nfs/mapper/sysvg-optlv
                      10M  2.3M  923M   1% /home
udev/mapper/sysvg-optlv
                      976M  2.3M  923M   1% /home
/dev/mapper/mpathap1  10M  141M  311M  32% /boot`;

const joinBreakedLines = function(result, currentLine) {
  if (currentLine.startsWith('   ')) {
    result[result.length - 1] += '  ' + currentLine.trim();
  } else {
    result.push(currentLine);
  }
  return result;
};

const sum = str
  .split('\n')
  .reduce(joinBreakedLines, [])
  .filter(function(line) {
    return !(line.startsWith('udev') || line.startsWith('nfs'));
  })
  .map(function(line) {
    return line.split('  ');
  })
  .reduce(function(result, line) {
    const value = line[1].slice(0, -1);
    return result + parseInt(value, 10);
  }, 0);

console.log(sum);

答案 3 :(得分:0)

我将这些行拆分为一个数组,并使用reduce()对其求和。这种方法的好处是,只需要循环遍历一次数组即可得出总和。

详细信息作为注释包含在代码中。

let lines = `/dev/mapper/mpathap1  10M  141M  311M  32% /boot
udev/mapper/sysvg-optlv 976M  2.3M  923M   1% /home
/dev/mapper/sysvg-homelv
                      10M  2.3M  923M   1% /home
nfs/mapper/sysvg-optlv
                      10M  2.3M  923M   1% /home
udev/mapper/sysvg-optlv
                      976M  2.3M  923M   1% /home
/dev/mapper/mpathap1  10M  141M  311M  32% /boot`;

var result = lines
  .split(/(?=\/dev\/|udev|nfs)/g)               //Split lines into array
  .reduce(function(sum, line) {
    if (!line.startsWith("/dev/")) return sum;  //Ignore lines that don't start with "/dev/"

    var diskspace = line.match(/\S+/g)[1];      //Split on spaces, get second value
    return diskspace.endsWith("G") ?            
      sum + parseInt(diskspace) * 1024 :        //gb - multiply by 1024
      sum + parseInt(diskspace);                //mb - leave as-is
  }, 0);

console.log(result);

答案 4 :(得分:0)

要获得预期的结果,请使用以下使用reduce,split,indexOf的选项

  1. 用下面的代码替换新行('\ n'),并用空格('')分割,并使用filter(Boolean)删除空值

    str.replace(/ \ n | \ r / g,“”).split('').filter(Boolean)

  2. 通过用'/'分割字符串并计数> 1并检查其是否以'udev'或'nfs'开头来检查路径

    v.split('/')。length> 1 &&!v.startsWith('nfs')&&!v.startsWith('udev')

  3. 如果第2步有效,则通过检查下一个值是否可用,已定义和编号,将下一个值添加到累加器值-acc中

if(i+1){ if(self[i+1] && !isNaN(parseInt(self[i+1])*1)){ acc =acc + parseInt(self[i+1])
} }

代码示例-

var str = `/dev/mapper/mpathap1  10M  141M  311M  32% /boot
udev/mapper/sysvg-optlv 976M  2.3M  923M   1% /home
/dev/mapper/sysvg-homelv
                      10M  2.3M  923M   1% /home
nfs/mapper/sysvg-optlv
                      10M  2.3M  923M   1% /home
udev/mapper/sysvg-optlv
                      976M  2.3M  923M   1% /home
/dev/mapper/mpathap1  10M  141M  311M  32% /boot
`

console.log(str.replace(/\n|\r/g, " ").split(' ').filter(Boolean).reduce((acc, v, i, self) => {
   if(v.split('/').length > 1 && !v.startsWith('nfs') &&  !v.startsWith('udev')){    
     if(i+1){
       if(self[i+1] && !isNaN(parseInt(self[i+1])*1)){
          acc =acc + parseInt(self[i+1])         
       }
     }
   }
   return acc
}, 0))

codepen-https://codepen.io/nagasai/pen/BgzLvQ?editors=1010