让我解释一下我在说什么。我有以下数组:
const days = [
{
date: '2016-12-13T00:00:00.000Z',
stats: [
{ name: 'A', sold: 34, },
{ name: 'B', sold: 3, },
{ name: 'C', sold: 26, },
],
},
{
date: '2016-12-14T00:00:00.000Z',
stats: [
{ name: 'D', sold: 34, },
{ name: 'E', sold: 3, },
{ name: 'F', sold: 26, },
],
},
{
date: '2016-12-14T00:00:00.000Z',
stats: [
{ name: 'D', sold: 34, },
{ name: 'E', sold: 3, },
{ name: 'F', sold: 26, },
],
},
];
我要做的是找到每个stat.name
的百分比,例如。如果我们合并了所有出售的价值:189
现在找到统计名%
的{{1}}
B
这会给我:(3 / 189) * 100
这代表该类别的已售商品的1.58%
。
理想情况下,我所追求的结果如下:
%
到目前为止我做了什么:
const result = [
{ name: 'A', sold: 34, percentage: '17,98%' },
{ name: 'B', sold: 3, percentage: '1,58%', },
{ name: 'C', sold: 26, percentage: '13,75%', },
{ name: 'D', sold: 68, percentage: '35,97%', },
{ name: 'E', sold: 6, percentage: '3,17%' },
{ name: 'F', sold 52, percentage: '27,51%' },
];
哪些产出:
const days = [
{
date: '2016-12-13T00:00:00.000Z',
stats: [
{ name: 'A', sold: 34, },
{ name: 'B', sold: 3, },
{ name: 'C', sold: 26, },
],
},
{
date: '2016-12-14T00:00:00.000Z',
stats: [
{ name: 'D', sold: 34, },
{ name: 'E', sold: 3, },
{ name: 'F', sold: 26, },
],
},
{
date: '2016-12-14T00:00:00.000Z',
stats: [
{ name: 'D', sold: 34, },
{ name: 'E', sold: 3, },
{ name: 'F', sold: 26, },
],
},
];
let total = 0;
days.map(record => record.stats.map(category => total += category.sold)); // save the total;
const newStats = days.reduce(function (pastDay, currentDay) {
const nextStats = currentDay.stats.map(function(stat) {
const oldSold = pastDay.stats.find((old) => old.name === stat.name); // object that match by name.
let newSold;
if (oldSold) { // if matched
newSold = stat.sold + oldSold.sold // sum
} else { // don't sum anything
newSold = stat.sold
}
stat.sold = newSold;
stat.percentage = `${(newSold / total * 100).toFixed(2)}%`;
return stat;
});
return {
stats: nextStats,
};
});
console.log(newStats);
A,B,C。已经走了..
对整件事情有没有更好的方法?我真的不喜欢绘图并获得总数,然后与其他人一起工作..有没有办法做得更好?感谢...
答案 0 :(得分:3)
您可以先收集已售出的计数,然后使用百分比渲染数组。
var days = [{ date: '2016-12-13T00:00:00.000Z', stats: [{ name: 'A', sold: 34, }, { name: 'B', sold: 3, }, { name: 'C', sold: 26, }, ], }, { date: '2016-12-14T00:00:00.000Z', stats: [{ name: 'D', sold: 34, }, { name: 'E', sold: 3, }, { name: 'F', sold: 26, }, ], }, { date: '2016-12-14T00:00:00.000Z', stats: [{ name: 'D', sold: 34, }, { name: 'E', sold: 3, }, { name: 'F', sold: 26, }, ], }, ],
temp = Object.create(null),
result = [],
total = 0;
days.forEach(function (day) {
day.stats.forEach(function (stat) {
total += stat.sold;
temp[stat.name] = (temp[stat.name] || 0) + stat.sold;
});
}, Object.create(null));
result = Object.keys(temp).map(function (k) {
return { name: k, sold: temp[k], percentage: (temp[k] * 100 / total).toFixed(2) + '%' };
});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 1 :(得分:1)
将Array#map
与Object#assign
和array spread一起使用,将所有统计数据合并到一个数组中。使用Array#reduce
得到总和。映射flatlist
,并使用template literal
const days = [{"date":"2016-12-13T00:00:00.000Z","stats":[{"name":"A","sold":34},{"name":"B","sold":3},{"name":"C","sold":26}]},{"date":"2016-12-14T00:00:00.000Z","stats":[{"name":"D","sold":34},{"name":"E","sold":3},{"name":"F","sold":26}]},{"date":"2016-12-14T00:00:00.000Z","stats":[{"name":"D","sold":34},{"name":"E","sold":3},{"name":"F","sold":26}]}];
// flatten the lists
const flatList = [].concat([], ...days.map(({ stats }) => stats ));
// get the sum
const sum = flatList.reduce(( sum, { sold }) => sum + sold, 0);
// assign the percentage to each
const result = flatList.map((stat) => Object.assign({}, stat, { percentage: `${(stat.sold / sum * 100).toFixed(2)}%` }));
console.log(result);

答案 2 :(得分:1)
我强烈建议你添加一些通用函数来抽象出一些复杂性。有很多方法可以做到这一点,但我会把它作为锻炼给你。如果我有更多时间,也许今天晚些时候我会更新答案。
以下是使用Array.prototype.reduce
const days = [ { date: '2016-12-13T00:00:00.000Z', stats: [ { name: 'A', sold: 34, }, { name: 'B', sold: 3, }, { name: 'C', sold: 26, }, ], }, { date: '2016-12-14T00:00:00.000Z', stats: [ { name: 'D', sold: 34, }, { name: 'E', sold: 3, }, { name: 'F', sold: 26, }, ], }, { date: '2016-12-14T00:00:00.000Z', stats: [ { name: 'D', sold: 34, }, { name: 'E', sold: 3, }, { name: 'F', sold: 26, } ] } ]
const makeSalesReport = days => {
let {map,sum} = days
.reduce((acc, {stats}) => [...acc, ...stats], [])
.reduce(({map, sum}, {name, sold}) => ({
map: map.set(name, map.has(name) ? map.get(name) + sold : sold),
sum: sum + sold
}), {map: new Map(), sum: 0})
return Array.from(map, ([name, sold]) =>
({name, sold, percentage: sold / sum * 100}))
}
console.log(makeSalesReport(days))
这是使用for-of
循环
const days = [ { date: '2016-12-13T00:00:00.000Z', stats: [ { name: 'A', sold: 34, }, { name: 'B', sold: 3, }, { name: 'C', sold: 26, }, ], }, { date: '2016-12-14T00:00:00.000Z', stats: [ { name: 'D', sold: 34, }, { name: 'E', sold: 3, }, { name: 'F', sold: 26, }, ], }, { date: '2016-12-14T00:00:00.000Z', stats: [ { name: 'D', sold: 34, }, { name: 'E', sold: 3, }, { name: 'F', sold: 26, } ] } ]
const makeSalesReport = days => {
let map = new Map(), sum = 0
for (let {stats} of days) {
for (let {name, sold} of stats) {
map.set(name, map.has(name) ? map.get(name) + sold : sold),
sum += sold
}
}
return Array.from(map, ([name, sold]) =>
({name, sold, percentage: sold / sum * 100}))
}
console.log(makeSalesReport(days))