I have an array of objects:
let data = [ {date:'2018-01-01', device: 'iphone', site: 'google', val1:10, val2:20, val3:30}, {date:'2018-01-01', device: 'iphone', site: 'bing', val1:23, val2:12, val3:14}, {date:'2018-01-01', device: 'iphone', site: 'jeeves', val1:67, val2:78, val3:12}, {date:'2018-01-01', device: 'ipad', site: 'google', val1:10, val2:20, val3:30}, {date:'2018-01-01', device: 'ipad', site: 'bing', val1:23, val2:12, val3:14}, {date:'2018-01-01', device: 'ipad', site: 'jeeves', val1:67, val2:78, val3:12}, {date:'2018-01-02', device: 'iphone', site: 'google', val1:11, val2:22, val3:33}, {date:'2018-01-02', device: 'iphone', site: 'bing', val1:25, val2:27, val3:28}, {date:'2018-01-02', device: 'iphone', site: 'jeeves', val1:67, val2:80, val3:15}, {date:'2018-01-02', device: 'ipad', site: 'google', val1:12, val2:21, val3:31}, {date:'2018-01-02', device: 'ipad', site: 'bing', val1:26, val2:16, val3:11}, {date:'2018-01-02', device: 'ipad', site: 'jeeves', val1:65, val2:79, val3:55}, {date:'2018-01-03', device: 'iphone', site: 'google', val1:17, val2:19, val3:11}, {date:'2018-01-03', device: 'iphone', site: 'bing', val1:13, val2:15, val3:12}, {date:'2018-01-03', device: 'iphone', site: 'jeeves', val1:69, val2:79, val3:15}, {date:'2018-01-03', device: 'ipad', site: 'google', val1:17, val2:51, val3:31}, {date:'2018-01-03', device: 'ipad', site: 'bing', val1:25, val2:15, val3:17}, {date:'2018-01-03', device: 'ipad', site: 'jeeves', val1:61, val2:71, val3:15} ]
I want to convert val1
to percentages based on the date and device.
So on 2018-01-01
if the device is iphone
I want the vals to be for example: val1 to be 10%
, 23%
& 67%
respectively.
My code so far:
let data = [ {date:'2018-01-01', device: 'iphone', site: 'google', val1:10, val2:20, val3:30}, {date:'2018-01-01', device: 'iphone', site: 'bing', val1:23, val2:12, val3:14}, {date:'2018-01-01', device: 'iphone', site: 'jeeves', val1:67, val2:78, val3:12}, {date:'2018-01-01', device: 'ipad', site: 'google', val1:10, val2:20, val3:30}, {date:'2018-01-01', device: 'ipad', site: 'bing', val1:23, val2:12, val3:14}, {date:'2018-01-01', device: 'ipad', site: 'jeeves', val1:67, val2:78, val3:12}, {date:'2018-01-02', device: 'iphone', site: 'google', val1:11, val2:22, val3:33}, {date:'2018-01-02', device: 'iphone', site: 'bing', val1:25, val2:27, val3:28}, {date:'2018-01-02', device: 'iphone', site: 'jeeves', val1:67, val2:80, val3:15}, {date:'2018-01-02', device: 'ipad', site: 'google', val1:12, val2:21, val3:31}, {date:'2018-01-02', device: 'ipad', site: 'bing', val1:26, val2:16, val3:11}, {date:'2018-01-02', device: 'ipad', site: 'jeeves', val1:65, val2:79, val3:55}, {date:'2018-01-03', device: 'iphone', site: 'google', val1:17, val2:19, val3:11}, {date:'2018-01-03', device: 'iphone', site: 'bing', val1:13, val2:15, val3:12}, {date:'2018-01-03', device: 'iphone', site: 'jeeves', val1:69, val2:79, val3:15}, {date:'2018-01-03', device: 'ipad', site: 'google', val1:17, val2:51, val3:31}, {date:'2018-01-03', device: 'ipad', site: 'bing', val1:25, val2:15, val3:17}, {date:'2018-01-03', device: 'ipad', site: 'jeeves', val1:61, val2:71, val3:15} ] //Grouping by date const group_data = data.reduce((a, c) => { (a[c['date']] = a[c['date']] || []).push(c); return a; }, {}); // I am able to sum the data but not % each of them. Here I am able to group by 2 value, that is 'date' and 'device' const grp_data = (grouped_data, first_group, second_group) => { for (const key of Object.keys(grouped_data)) { const map_data = new Map(); for (const { [first_group]: date, [second_group]: device, ...other_vals } of grouped_data[key]) { const row = map_data.get(date + ',' + device) || { date, device } Object.entries(other_vals).forEach(([k, v]) => { if (/^[0-9,.]*$/.test(v) === true && typeof v !== 'number') v = parseFloat(v.replace(/,/gi, '')); row[k] = (row[k] || 0) + v }); map_data.set(date + ',' + device, row); } grouped_data[key] = [...map_data.values()]; } } grp_data(group_data, 'date', 'device'); console.log(group_data);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
While I am able to group the data by 2 keys, I am not sure how to convert the val1’s to %’s.
I am not sure how to go from here to get this as the data:
{date:'2018-01-01', device: 'iphone', site: 'google', val1:10%, val2:18.18%, val3:53.57%}, {date:'2018-01-01', device: 'iphone', site: 'bing', val1:23%, val2:10.90%, val3:25%}, {date:'2018-01-01', device: 'iphone', site: 'jeeves', val1:67%, val2:70.90%, val3:21.42%}, ...
Advertisement
Answer
As per your explanation, I tried this in completely different way.
let data = [ {date:'2018-01-01', device: 'iphone', site: 'google', val1:10, val2:20, val3:30}, {date:'2018-01-01', device: 'iphone', site: 'bing', val1:23, val2:12, val3:14}, {date:'2018-01-01', device: 'iphone', site: 'jeeves', val1:67, val2:78, val3:12}, {date:'2018-01-01', device: 'ipad', site: 'google', val1:10, val2:20, val3:30}, {date:'2018-01-01', device: 'ipad', site: 'bing', val1:23, val2:12, val3:14}, {date:'2018-01-01', device: 'ipad', site: 'jeeves', val1:67, val2:78, val3:12}, {date:'2018-01-02', device: 'iphone', site: 'google', val1:11, val2:22, val3:33}, {date:'2018-01-02', device: 'iphone', site: 'bing', val1:25, val2:27, val3:28}, {date:'2018-01-02', device: 'iphone', site: 'jeeves', val1:67, val2:80, val3:15}, {date:'2018-01-02', device: 'ipad', site: 'google', val1:12, val2:21, val3:31}, {date:'2018-01-02', device: 'ipad', site: 'bing', val1:26, val2:16, val3:11}, {date:'2018-01-02', device: 'ipad', site: 'jeeves', val1:65, val2:79, val3:55}, {date:'2018-01-03', device: 'iphone', site: 'google', val1:17, val2:19, val3:11}, {date:'2018-01-03', device: 'iphone', site: 'bing', val1:13, val2:15, val3:12}, {date:'2018-01-03', device: 'iphone', site: 'jeeves', val1:69, val2:79, val3:15}, {date:'2018-01-03', device: 'ipad', site: 'google', val1:17, val2:51, val3:31}, {date:'2018-01-03', device: 'ipad', site: 'bing', val1:25, val2:15, val3:17}, {date:'2018-01-03', device: 'ipad', site: 'jeeves', val1:61, val2:71, val3:15} ] let dataObj = {}; data.forEach(d => { if(!dataObj[d.date]) dataObj[d.date] = {}; if(!dataObj[d.date][d.device]) dataObj[d.date][d.device] = {}; if(!dataObj[d.date][d.device].val1) dataObj[d.date][d.device].val1 = 0; if(!dataObj[d.date][d.device].val2) dataObj[d.date][d.device].val2 = 0; if(!dataObj[d.date][d.device].val3) dataObj[d.date][d.device].val3 = 0; dataObj[d.date][d.device].val1 += d.val1; dataObj[d.date][d.device].val2 += d.val2; dataObj[d.date][d.device].val3 += d.val3; }); data.forEach(d => { d.val1 = d.val1 * 100 / dataObj[d.date][d.device].val1; d.val2 = d.val2 * 100 / dataObj[d.date][d.device].val2; d.val3 = d.val3 * 100 / dataObj[d.date][d.device].val3; }); console.log(data);