2

I have an object, where i want to calculate the percentage and display in the maps, currently the data i am getting is a raw data in an object.

Here is the object that i am receiving from backend

          [{
            "date": "26/08/2021",
            "walking": 965.2107,
            "running": 964.0539,
            "sleeping": 962.1473,
            "swimming": 961.8081,
            "studying": 961.5081,
          }]

Based on the object i want the percentage to be calculated and replaced in the respective key/value pair. It will take the object value, sum it up and calculate the percentage. This is what i am expecting to return

          [{
            "date": "26/08/2021",
            "walking": 20,
            "running": 20,
            "sleeping": 20,
            "swimming": 20,
            "studying": 20,
          }]
tkamath99
  • 629
  • 1
  • 12
  • 32
  • Where are you stuck? – Cid Aug 26 '21 at 08:34
  • @Cid am known to use Object.values. So the idea was to get the Object.values and Object.keys to get the value and calculate the percentage using reduce method. But the data i am receiving is an array of object. So using Object.keys and Object.values is giving me error – tkamath99 Aug 26 '21 at 08:36
  • Does this answer your question? [Javascript reduce() on Object](https://stackoverflow.com/questions/15748656/javascript-reduce-on-object) – Cyrus Raoufi Aug 26 '21 at 08:39
  • Show us what you've tried with the error messages you get – Cid Aug 26 '21 at 08:41

2 Answers2

1

Array.prototype.map and Array.prototype.reduce (over object keys) is all you need,

const arr =  [{
  "date": "26/08/2021",
  "walking": 965.2107,
  "running": 964.0539,
  "sleeping": 962.1473,
  "swimming": 961.8081,
  "studying": 961.5081,
}];
          
const transformedArr = arr.map((item) => {
  const totalSum = Object.keys(item).reduce((prev, key) => {
    if(key === "date") return 0;
    return prev + item[key];
  }, 0);
  
  return Object.keys(item).reduce((prev, key) => {
    if(key === "date") return {...prev, [key]: item[key] };
    return {...prev, [key]: (item[key]/totalSum) * 100 }
  }, {});
});

console.log(transformedArr);

PS: If you want a strict integer value, you can use parseInt, Math.ceil or Math.round depending on your need

Utkarsh Dixit
  • 4,267
  • 3
  • 15
  • 38
1

const data = [{
  "date": "26/08/2021",
  "walking": 965.2107,
  "running": 964.0539,
  "sleeping": 962.1473,
  "swimming": 961.8081,
  "studying": 961.5081,
}];

const dataInPerCents = data.map(item => {
  const itemCopy = {...item};
  const keys = Object.keys(itemCopy).filter(key => key !== "date");
  const sum = keys.reduce((sum, key) => sum + itemCopy[key], 0);
  keys.forEach(key => itemCopy[key] = Math.round(100 * itemCopy[key] / sum));
  itemCopy.top3 = keys.sort((key1, key2) => item[key2] - item[key1]).slice(0, 3); // Asked in comment below
  return itemCopy;
});
console.log(dataInPerCents);
kol
  • 27,881
  • 12
  • 83
  • 120
  • Thanks for all your help! Received 2 solutions. But marked Utkarsh solution as correct. – tkamath99 Aug 26 '21 at 08:47
  • Can you help me find the Highest Top 3 from the object during the reduce method. – tkamath99 Aug 26 '21 at 13:16
  • Higest in what sense? The 3 objects with the highest `walking` percent for example? – kol Aug 26 '21 at 13:19
  • No.. The top 3 highest values in an object. So the console.log(data) shall only contain 3 values which will be the highest from an object. – tkamath99 Aug 26 '21 at 13:21
  • I would keep all fields as they are now, and add a new array field to each object, called `top3`, which would contain the name of the top 3 fields. I modified my answer. – kol Aug 26 '21 at 13:38
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/236446/discussion-between-tkamath99-and-kol). – tkamath99 Aug 26 '21 at 13:40