I have an array of objects:
JavaScript
x
21
21
1
let data = [
2
{date:'2018-01-01', device: 'iphone', site: 'google', val1:10, val2:20, val3:30},
3
{date:'2018-01-01', device: 'iphone', site: 'bing', val1:23, val2:12, val3:14},
4
{date:'2018-01-01', device: 'iphone', site: 'jeeves', val1:67, val2:78, val3:12},
5
{date:'2018-01-01', device: 'ipad', site: 'google', val1:10, val2:20, val3:30},
6
{date:'2018-01-01', device: 'ipad', site: 'bing', val1:23, val2:12, val3:14},
7
{date:'2018-01-01', device: 'ipad', site: 'jeeves', val1:67, val2:78, val3:12},
8
{date:'2018-01-02', device: 'iphone', site: 'google', val1:11, val2:22, val3:33},
9
{date:'2018-01-02', device: 'iphone', site: 'bing', val1:25, val2:27, val3:28},
10
{date:'2018-01-02', device: 'iphone', site: 'jeeves', val1:67, val2:80, val3:15},
11
{date:'2018-01-02', device: 'ipad', site: 'google', val1:12, val2:21, val3:31},
12
{date:'2018-01-02', device: 'ipad', site: 'bing', val1:26, val2:16, val3:11},
13
{date:'2018-01-02', device: 'ipad', site: 'jeeves', val1:65, val2:79, val3:55},
14
{date:'2018-01-03', device: 'iphone', site: 'google', val1:17, val2:19, val3:11},
15
{date:'2018-01-03', device: 'iphone', site: 'bing', val1:13, val2:15, val3:12},
16
{date:'2018-01-03', device: 'iphone', site: 'jeeves', val1:69, val2:79, val3:15},
17
{date:'2018-01-03', device: 'ipad', site: 'google', val1:17, val2:51, val3:31},
18
{date:'2018-01-03', device: 'ipad', site: 'bing', val1:25, val2:15, val3:17},
19
{date:'2018-01-03', device: 'ipad', site: 'jeeves', val1:61, val2:71, val3:15}
20
]
21
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:
JavaScript
1
52
52
1
let data = [
2
{date:'2018-01-01', device: 'iphone', site: 'google', val1:10, val2:20, val3:30},
3
{date:'2018-01-01', device: 'iphone', site: 'bing', val1:23, val2:12, val3:14},
4
{date:'2018-01-01', device: 'iphone', site: 'jeeves', val1:67, val2:78, val3:12},
5
{date:'2018-01-01', device: 'ipad', site: 'google', val1:10, val2:20, val3:30},
6
{date:'2018-01-01', device: 'ipad', site: 'bing', val1:23, val2:12, val3:14},
7
{date:'2018-01-01', device: 'ipad', site: 'jeeves', val1:67, val2:78, val3:12},
8
{date:'2018-01-02', device: 'iphone', site: 'google', val1:11, val2:22, val3:33},
9
{date:'2018-01-02', device: 'iphone', site: 'bing', val1:25, val2:27, val3:28},
10
{date:'2018-01-02', device: 'iphone', site: 'jeeves', val1:67, val2:80, val3:15},
11
{date:'2018-01-02', device: 'ipad', site: 'google', val1:12, val2:21, val3:31},
12
{date:'2018-01-02', device: 'ipad', site: 'bing', val1:26, val2:16, val3:11},
13
{date:'2018-01-02', device: 'ipad', site: 'jeeves', val1:65, val2:79, val3:55},
14
{date:'2018-01-03', device: 'iphone', site: 'google', val1:17, val2:19, val3:11},
15
{date:'2018-01-03', device: 'iphone', site: 'bing', val1:13, val2:15, val3:12},
16
{date:'2018-01-03', device: 'iphone', site: 'jeeves', val1:69, val2:79, val3:15},
17
{date:'2018-01-03', device: 'ipad', site: 'google', val1:17, val2:51, val3:31},
18
{date:'2018-01-03', device: 'ipad', site: 'bing', val1:25, val2:15, val3:17},
19
{date:'2018-01-03', device: 'ipad', site: 'jeeves', val1:61, val2:71, val3:15}
20
]
21
22
//Grouping by date
23
const group_data = data.reduce((a, c) => {
24
(a[c['date']] = a[c['date']] || []).push(c);
25
return a;
26
}, {});
27
28
29
// 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'
30
const grp_data = (grouped_data, first_group, second_group) => {
31
for (const key of Object.keys(grouped_data)) {
32
const map_data = new Map();
33
for (const {
34
[first_group]: date, [second_group]: device, other_vals
35
}
36
of grouped_data[key]) {
37
const row = map_data.get(date + ',' + device) || {
38
date,
39
device
40
}
41
Object.entries(other_vals).forEach(([k, v]) => {
42
if (/^[0-9,.]*$/.test(v) === true && typeof v !== 'number') v = parseFloat(v.replace(/,/gi, ''));
43
row[k] = (row[k] || 0) + v
44
});
45
map_data.set(date + ',' + device, row);
46
}
47
grouped_data[key] = [map_data.values()];
48
}
49
}
50
grp_data(group_data, 'date', 'device');
51
52
console.log(group_data);
JavaScript
1
1
1
<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:
JavaScript
1
5
1
{date:'2018-01-01', device: 'iphone', site: 'google', val1:10%, val2:18.18%, val3:53.57%},
2
{date:'2018-01-01', device: 'iphone', site: 'bing', val1:23%, val2:10.90%, val3:25%},
3
{date:'2018-01-01', device: 'iphone', site: 'jeeves', val1:67%, val2:70.90%, val3:21.42%},
4
5
Advertisement
Answer
As per your explanation, I tried this in completely different way.
JavaScript
1
40
40
1
let data = [
2
{date:'2018-01-01', device: 'iphone', site: 'google', val1:10, val2:20, val3:30},
3
{date:'2018-01-01', device: 'iphone', site: 'bing', val1:23, val2:12, val3:14},
4
{date:'2018-01-01', device: 'iphone', site: 'jeeves', val1:67, val2:78, val3:12},
5
{date:'2018-01-01', device: 'ipad', site: 'google', val1:10, val2:20, val3:30},
6
{date:'2018-01-01', device: 'ipad', site: 'bing', val1:23, val2:12, val3:14},
7
{date:'2018-01-01', device: 'ipad', site: 'jeeves', val1:67, val2:78, val3:12},
8
{date:'2018-01-02', device: 'iphone', site: 'google', val1:11, val2:22, val3:33},
9
{date:'2018-01-02', device: 'iphone', site: 'bing', val1:25, val2:27, val3:28},
10
{date:'2018-01-02', device: 'iphone', site: 'jeeves', val1:67, val2:80, val3:15},
11
{date:'2018-01-02', device: 'ipad', site: 'google', val1:12, val2:21, val3:31},
12
{date:'2018-01-02', device: 'ipad', site: 'bing', val1:26, val2:16, val3:11},
13
{date:'2018-01-02', device: 'ipad', site: 'jeeves', val1:65, val2:79, val3:55},
14
{date:'2018-01-03', device: 'iphone', site: 'google', val1:17, val2:19, val3:11},
15
{date:'2018-01-03', device: 'iphone', site: 'bing', val1:13, val2:15, val3:12},
16
{date:'2018-01-03', device: 'iphone', site: 'jeeves', val1:69, val2:79, val3:15},
17
{date:'2018-01-03', device: 'ipad', site: 'google', val1:17, val2:51, val3:31},
18
{date:'2018-01-03', device: 'ipad', site: 'bing', val1:25, val2:15, val3:17},
19
{date:'2018-01-03', device: 'ipad', site: 'jeeves', val1:61, val2:71, val3:15}
20
]
21
22
let dataObj = {};
23
data.forEach(d => {
24
if(!dataObj[d.date]) dataObj[d.date] = {};
25
if(!dataObj[d.date][d.device]) dataObj[d.date][d.device] = {};
26
if(!dataObj[d.date][d.device].val1) dataObj[d.date][d.device].val1 = 0;
27
if(!dataObj[d.date][d.device].val2) dataObj[d.date][d.device].val2 = 0;
28
if(!dataObj[d.date][d.device].val3) dataObj[d.date][d.device].val3 = 0;
29
dataObj[d.date][d.device].val1 += d.val1;
30
dataObj[d.date][d.device].val2 += d.val2;
31
dataObj[d.date][d.device].val3 += d.val3;
32
});
33
34
data.forEach(d => {
35
d.val1 = d.val1 * 100 / dataObj[d.date][d.device].val1;
36
d.val2 = d.val2 * 100 / dataObj[d.date][d.device].val2;
37
d.val3 = d.val3 * 100 / dataObj[d.date][d.device].val3;
38
});
39
40
console.log(data);