按标签合并数组并计算流媒体数据分组均值
按班次分组计算流媒体频道平均值解决方案
需求说明
将给定的按班次(manha=上午、tarde=下午)分类的流媒体频道数据,按标签分组后,对每组内各频道的数值求和,再除以组内数据的数量,得到各频道的平均值,最终输出和原始结构一致的数组。
原始数据
const array = [{"label":"manha","data":[{"Amazon Prime":"0.00"},{"AppleTV":"0.00"},{"HBO Max":"25.00"},{"Nenhuma":"0.00"},{"Netflix":"55.00"},{"Outro":"20.00"}]},{"label":"manha","data":[{"Amazon Prime":"50.00"},{"AppleTV":"0.00"},{"HBO Max":"25.00"},{"Nenhuma":"0.00"},{"Netflix":"25.00"},{"Outro":"0.00"}]},{"label":"manha","data":[{"Amazon Prime":"0.00"},{"AppleTV":"0.00"},{"HBO Max":"0.00"},{"Nenhuma":"50.00"},{"Netflix":"50.00"},{"Outro":"0.00"}]},{"label":"tarde","data":[{"Amazon Prime":"10.00"},{"AppleTV":"11.00"},{"HBO Max":"0.00"},{"Nenhuma":"50.00"},{"Netflix":"9.00"},{"Outro":"20.00"}]},{"label":"tarde","data":[{"Amazon Prime":"0.00"},{"AppleTV":"0.00"},{"HBO Max":"5.00"},{"Nenhuma":"25.00"},{"Netflix":"20.00"},{"Outro":"50.00"}]}];
期望输出
[{"label":"manha","data":[{"Amazon Prime":"16.66"},{"AppleTV":"0.00"},{"HBO Max":"16.66"},{"Nenhuma":"16.66"},{"Netflix":"43.33"},{"Outro":"6.66"}]},{"label":"tarde","data":[{"Amazon Prime":"5.00"},{"AppleTV":"5.50"},{"HBO Max":"2.50"},{"Nenhuma":"36.00"},{"Netflix":"14.50"},{"Outro":"35.00"}]}]
实现代码
const array = [{"label":"manha","data":[{"Amazon Prime":"0.00"},{"AppleTV":"0.00"},{"HBO Max":"25.00"},{"Nenhuma":"0.00"},{"Netflix":"55.00"},{"Outro":"20.00"}]},{"label":"manha","data":[{"Amazon Prime":"50.00"},{"AppleTV":"0.00"},{"HBO Max":"25.00"},{"Nenhuma":"0.00"},{"Netflix":"25.00"},{"Outro":"0.00"}]},{"label":"manha","data":[{"Amazon Prime":"0.00"},{"AppleTV":"0.00"},{"HBO Max":"0.00"},{"Nenhuma":"50.00"},{"Netflix":"50.00"},{"Outro":"0.00"}]},{"label":"tarde","data":[{"Amazon Prime":"10.00"},{"AppleTV":"11.00"},{"HBO Max":"0.00"},{"Nenhuma":"50.00"},{"Netflix":"9.00"},{"Outro":"20.00"}]},{"label":"tarde","data":[{"Amazon Prime":"0.00"},{"AppleTV":"0.00"},{"HBO Max":"5.00"},{"Nenhuma":"25.00"},{"Netflix":"20.00"},{"Outro":"50.00"}]}]; // 提取固定的频道名称顺序,保证输出结构和输入一致 const channelNames = array[0].data.map(item => Object.keys(item)[0]); // 用reduce完成分组、计数和总和累加 const groupedData = array.reduce((accumulator, currentItem) => { const { label, data } = currentItem; // 初始化分组结构(如果该班次还未被记录) if (!accumulator[label]) { accumulator[label] = { count: 0, totalSums: Object.fromEntries(channelNames.map(name => [name, 0])) }; } // 该班次数据量+1 accumulator[label].count += 1; // 遍历当前数据的每个频道,累加数值 data.forEach(channelObj => { const [channelName, valueStr] = Object.entries(channelObj)[0]; accumulator[label].totalSums[channelName] += parseFloat(valueStr); }); return accumulator; }, {}); // 将分组结果转换为目标格式 const finalResult = Object.entries(groupedData).map(([label, groupInfo]) => { const { count, totalSums } = groupInfo; const averageData = channelNames.map(name => { // 计算平均值并保留两位小数,转为字符串 const average = (totalSums[name] / count).toFixed(2); return { [name]: average }; }); return { label, data: averageData }; }); console.log(JSON.stringify(finalResult));
逻辑解释
- 提取频道顺序:从第一个数据项的
data中提取频道名称列表,确保最终输出的频道顺序和原始数据完全一致,避免结构混乱。 - reduce分组处理:
- 初始化一个空对象作为累加器,用来存储每个班次的
数据数量和各频道数值总和。 - 遍历每一条数据,根据
label找到对应的分组,若不存在则初始化分组的计数和总和。 - 每处理一条数据,对应班次的计数加1,同时将当前数据中各频道的数值转为数字后累加到总和里。
- 初始化一个空对象作为累加器,用来存储每个班次的
- 转换为目标格式:
- 遍历分组后的对象,对每个班次的各频道总和除以计数得到平均值,用
toFixed(2)保留两位小数并转为字符串。 - 把每个频道的平均值包装成和原始
data一致的对象结构,最后组合成包含label和data的对象,组成最终数组。
- 遍历分组后的对象,对每个班次的各频道总和除以计数得到平均值,用
内容的提问来源于stack exchange,提问作者Guilherme Lirio
相关产品推荐
相关产品推荐

