Home > front end >  sum up text values in JSON Array
sum up text values in JSON Array

Time:02-24

i am in a bit tricky situation. I fetch some price values from a sqlite db and store it in a react state.

the response looks like: [{"price":50},{"price":"49,95"}]

i need to store these values as TEXT insted of INTEGER, because i have a lot of differrent decimal places. also using float in sqlite will not give me exact values, see the problem in this example: https://dba.stackexchange.com/questions/15729/storing-prices-in-sqlite-what-data-type-to-use

So to my main problem: how can i extract and convert the values from the json array to numbers, and sum it up?

CodePudding user response:

If you don't want to use a library, you could convert all numbers to strings and write your own sum function for strings. This algorithm supports arbitrary long strings containing numbers and returns exact results without rounding errors.

function add(l, r, sep) {
  if (!sep) sep = '.';
  const [ll, lr] = l.split(/[,.]/).map(el => el.split('').map(Number));
  const [rl, rr] = r.split(/[,.]/).map(el => el.split('').map(Number));
  let carry = 0;
  const result = [[], []];
  for (let i = Math.max(lr?.length ?? 0, rr?.length ?? 0); i > 0; --i) {
    result[1][i - 1] = (lr?.[i - 1] ?? 0)   (rr?.[i - 1] ?? 0)   carry;
    carry = Math.floor(result[1][i - 1] / 10);
    result[1][i - 1] %= 10;
  }
  
  for (let il = ll.length, ir = rl.length, iResult = Math.max(ll.length, rl.length); iResult > 0; --il, --ir, --iResult) {
    result[0][iResult - 1] = (ll[il - 1] ?? 0)   (rl[ir - 1] ?? 0)   carry;
    carry = Math.floor(result[0][iResult - 1] / 10);
    result[0][iResult - 1] %= 10;
  }
  if (carry) result[0] = [carry, ...result[0]];
  return result[0].join('')   sep   result[1].join('');
}

function sum(arr, sep) {
  return arr.map(el => String(el.price)).reduce((acc, el) => add(acc, el, sep));
}

console.log(sum([{ "price": "0.9" }, { "price": "1.2" }], ','));
console.log(sum([{ "price": "100000000" }, { "price": "0.0000002" }]));
console.log(sum([{ "price": 123.123 }, { "price": "1234.5678" }, { "price": "9876,54321" }, { "price": "111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111.111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"}]));

  • Related