1

I have arr array of objects, I need to pivot it with product,calorie and apply (grouping & sum) on remaining parameters.

And then require data in single object. I tried below code, it works fine but I divided code in 3 parts. Could I have better code than this or it is ok.

var arr = [{
    "product": "Jam",
    "calorie": 2000,
    "A": 300,
    "B": 500,
    "type": "Daily"
  },
  {
    "product": "Sugar",
    "calorie": 1000,
    "A": 100,
    "B": 200,
    "type": "Daily"
  }
]


var a1 = {}
var a2 = {}

//Step-1 Pivot
for (let i = 0; i < arr.length; i++) {
  a1[arr[i]['product']] = arr[i]['calorie'];
}
//Step-2 Group and sum
a2 = groupAndSum(arr, ['type'], ['A', 'B'])[0];

//Step-3 merging.
console.log({ ...a1,
  ...a2
})
//General grouping and summing function that accepts an 
  //@Array:Array of objects
  //@groupKeys: An array of keys to group by,
  //@sumKeys - An array of keys to sum.
function groupAndSum(arr, groupKeys, sumKeys) {
  return Object.values(
    arr.reduce((acc, curr) => {
      const group = groupKeys.map(k => curr[k]).join('-');
      acc[group] = acc[group] || Object.fromEntries(groupKeys.map(k => [k, curr[k]]).concat(sumKeys.map(k => [k, 0])));
      sumKeys.forEach(k => acc[group][k] += curr[k]);
      return acc;
    }, {})
  );
}

1 Answers1

1

Here a single function which takes 3 params:


const func = (arr, pivot_vals, sum_vals) => {
  return arr.reduce((a, v) => {
    pivot_vals.forEach((pivot) => {
      a[v[pivot[0]]] = v[pivot[1]];
    });
    sum_vals.forEach((key) => {
      if (!a[key]) a[key] = 0;
      a[key] += v[key];
    });
    return a;
  },{});
};

arr containing the data

sum_vals array with all props you want do be summed

pivot_vals nested array with the props which should be linked

I wans't sure what to do with the type, since it is a string it can`t be summed. Did you want to count the amount of types ?

let arr = [
  {
    product: "Jam",
    calorie: 2000,
    A: 300,
    B: 500,
    type: "Daily",
  },
  {
    product: "Sugar",
    calorie: 1000,
    A: 100,
    B: 200,
    type: "Daily",
  },
];

let sum_vals = ["A","B"]

let pivot_vals = [["product", "calorie"]];

const func = (arr, pivot_vals, sum_vals) => {
  return arr.reduce((a, v) => {
    pivot_vals.forEach((pivot) => {
      a[v[pivot[0]]] = v[pivot[1]];
    });
    sum_vals.forEach((key) => {
      if (!a[key]) a[key] = 0;
      a[key] += v[key];
    });
    return a;
  },{});
};

console.log(func(arr, pivot_vals, sum_vals));
DiniFarb
  • 206
  • 2
  • 6