获取用大括号插值的总数

时间:2018-03-20 16:38:53

标签: arrays typescript object functional-programming

我有一个如下所示的对象,我需要找到总数,包括大括号内外的数字。

 this.count = {
      "count1": "250 (220)",
      "count2": "125 (100)",
      "count3": "125 (100)",
      "count4": "125 (100)"
    }
  

预期结果:总和:“625(520)”

通过以下逻辑,我找不到第一组字符串的总和,即。,625:

let total=this.getTotal(this.count);

 public getTotal(count) {
         const count1 = parseInt(items.count1.split(' ')[0]);
         const count2 = parseInt(items.count2.split(' ')[0]);
         const count3 = parseInt(items.count3.split(' ')[0]);
         const count4 = parseInt(items.count4.split(' ')[0]);
         const totalA = count1 + count2 + count3 + count4;
         console.log(totalA);
    }

但我无法明智地分割()以计算其他部分并与totalA结合。请让我知道任何最适合计算这些类型对象的功能方法。谢谢

9 个答案:

答案 0 :(得分:3)

您可以使用reduce()方法获取一个对象,然后创建一个字符串。



const data = {"count1": "250 (220)","count2": "125 (100)","count3": "125 (100)","count4": "125 (100)"}

const total = Object.values(data).reduce((r, e) => {
  const [a, b] = e.split(/\(([^)]+)\)/);
  r.a = (r.a || 0) + +a;
  r.b = (r.b || 0) + +b;
  return r;
}, {})

const result = `Sum: ${total.a} (${total.b})`
console.log(result)




您还可以在reduce内部使用数组作为累加器,并在内部使用forEach()循环。



const data = {"count1": "250 (220)","count2": "125 (100)","count3": "125 (100)","count4": "125 (100)"}

const [a, b] = Object.values(data).reduce((r, e) => {
  e.split(/\(([^)]+)\)/).forEach((e, i) => r[i] += +e)
  return r;
}, [0, 0])

const result = `Sum: ${a} (${b})`
console.log(result)




答案 1 :(得分:2)

将工作分解为例如Count模块使得任务更容易



const Count =
  { fromString: s =>
      s.match (/\d+/g) .map (Number)
      
  , toString: ([a, b]) =>
      `${a} (${b})`
      
  , concat: ([a1, b1], [a2, b2]) =>
      [ a1 + a2, b1 + b2 ]
    
  , empty:
      [0, 0]
  }

const main = data =>
{
  const result =
    data.map (Count.fromString)
        .reduce (Count.concat, Count.empty)
  console.log (Count.toString (result))
}

const data =
  { "count1": "250 (220)"
  , "count2": "125 (100)"
  , "count3": "125 (100)"
  , "count4": "125 (100)"
  }

main (Object.values (data))




上面的.map - .reduce组合会导致两个循环,从而产生不必要的中间值。使用通用组合子mapReduce,我们可以将循环折叠成一个 - 粗体

中的变化
const mapReduce = (m, r) =>
  (acc, x) => r (acc, m (x))

const main = data =>
{
  const result =
    data.reduce (mapReduce (Count.fromString, Count.concat), Count.empty)
  console.log (Count.toString (result))
}

答案 2 :(得分:1)

使用Array.prototype.reduce这可行:

let count = {
  "count1": "250 (220)",
  "count2": "125 (100)",
  "count3": "125 (100)",
  "count4": "125 (100)"
}

let totalCount1 = Object.values(count).reduce(function(acc, val) {
  return acc + parseInt(val.split(' ')[0])
}, 0) 

let totalCount2 = Object.values(count).reduce(function(acc, val) {
  return acc + parseInt(val.split('(').pop().split(')')[0])
}, 0) 

console.log(`${totalCount1} (${totalCount2})`)

答案 3 :(得分:1)

由于您已经标记了"功能编程",这里有一个可能的FP解决方案:



// utilities

let map = (f, xs) => [...xs].map(f);
let sum = xs => xs.reduce((a, b) => Number(a) + Number(b));
let zip = (...xss) => xss[0].map((_, i) => xss.map(xs => xs[i]));

// here we go

count = {
    "count1": "250 (220) 10",
    "count2": "125 (100) 20",
    "count3": "125 (100) 30",
    "count4": "125 (100) 40"
};


res = map(sum, zip(
    ...map(
        s => s.match(/\d+/g),
        Object.values(count)
)));

console.log(res);




(我已经添加了第三列以使事情变得更有趣。代码适用于任意数量的列。)

话虽如此,对您的问题的真正的解决方案是首先修复破坏的数据结构。

答案 4 :(得分:1)

这似乎做你想要的,我认为是相当可读的:

const data = {"count1": "250 (220)","count2": "125 (100)","count3": "125 (100)","count4": "125 (100)"}

const splitSum = (data) => {
  const [a, b] = Object.values(data).reduce(([a0, b0], e) => {
    const [a1, b1] = e.split(/[^\d]+/).map(Number);
    return [a0 + a1, b0 + b1];
  }, [0, 0])
  return `Sum: ${a} (${b})`
}

console.log(splitSum(data))

答案 5 :(得分:0)

为了提高你的智慧(你可以使用RegEx来解决这个问题):

var count = {
  "count1": "250 (220)",
  "count2": "125 (100)",
  "count3": "125 (100)",
  "count4": "125 (100)"
}
function getTotal(items) {
     let sum = 0
     let sum1 = 0
     for (let i in items) {
         let item = items[i]
         sum += Number.parseInt(item.split(' ')[0])
         sum1 += Number.parseInt(item.split(' ')[1].replace(/^\(|\)$/g, ''))
     }
     console.log('Sum: ' + sum + ' (' + sum1 + ')')
}
getTotal(count)

答案 6 :(得分:0)

您可以对数组使用Object.values()forEach函数。

var count = {
        "count1": "250 (220)",
        "count2": "125 (100)",
        "count3": "125 (100)",
        "count4": "125 (100)"
    },
    lsum = 0,
    rsum = 0;

Object.values(count).forEach(v => {
    v = v.replace('(', '').replace(')', '').split(' ');
    lsum += +v[0];
    rsum += +v[1];
});
console.log(`${lsum} (${rsum})`)

答案 7 :(得分:0)

您对this的引用表明您还没有向我们展示您使用public这个词在JavaScript中无效。

但是,您可以循环遍历对象中的键并使用.split(与您使用它有点不同)来获取值的每个部分的总计。



var count = {
    "count1": "250 (220)",
    "count2": "125 (100)",
    "count3": "125 (100)",
    "count4": "125 (100)" 
};

function getTotal(count) {
    let val1 = 0;
    let val2 = 0;
   
    for(var key in count){
      val1 += parseInt(count[key].split(" (")[0], 10);
      val2 += parseInt(count[key].split(" (")[1], 10);    
    }

    return "Sum 1: " + val1 + " - Sum 2: " + val2;
}

console.log(getTotal(count));




答案 8 :(得分:0)

这是一个基于reduce的详细解决方案:

  const count = {
    "count1": "250 (220)",
    "count2": "125 (100)",
    "count3": "125 (100)",
    "count4": "125 (100)"
  };

  const rowPattern = /(\d+) \((\d+)\)/;

  const parseRow = row => row.match(rowPattern).slice(1, 3).map(s => parseInt(s));

  const result = Object.values(count).reduce((a, b) => {
    const [ outerA, innerA ] = parseRow(a),
      [ outerB, innerB ] = parseRow(b);
    return `${outerA + outerB} (${innerA + innerB})`;
  }, '0 (0)');

  console.log(result); // 625 (520)