我有如下格式的数据数组
let input = [
{
time: "2020-7",
tasks: [
{
key: "p1",
value: 15
},
{
key: "p2",
value: 13
},
]
},
{
time: "2020-8",
tasks: [
{
key: "p1",
value: 16
},
{
key: "p2",
value: 19
},
]
},
{
time: "2020-9",
tasks: [
{
key: "p1",
value: 12
},
{
key: "p2",
value: 93
},
]
}
]配置输入数组之后,“dataConvert”格式如下:
dataConvert = [
["x","2020-7", "2020-8", "2020-9"],
["p1", 15, 16, 12],
["p2", 13, 19, 93]
]我试过使用reduce,我想找到另一种优化方法。
let dateConvert = [], valueConvert = [];
data2.forEach(x=>{
let date = new Date(x.time);
if (date) {
let getYear = date.getFullYear();
let getMonth = date.getMonth() + 1;
let newDate = `${getYear}-${getMonth}-1`;
return dateConvert = [...dateConvert, newDate];
}
})
dateConvert.unshift("x");
// get p1 p2 value
let allTasks = data2.flatMap(x => x.tasks);
valueConvert = Object.values(allTasks.reduce((arr, item) => {
arr[item.key] = arr[item.key] || [item.key];
arr[item.key].push(item.value);
return arr;
}, {}));
dataConvert = [...[dateConvert], ...valueConvert];谢谢你。
发布于 2020-09-04 08:29:40
一次简短的回顾;
x部分是不同的;我假设代码是正确的reduce很好,这是代码中最好的部分dataConvert = [...[dateConvert], ...valueConvert];和dateConvert.unshift("x");,这可能是dateConvert = ["x", ...dateConvert];,unshift的唯一好理由可能是dateConvert是一个const,但它不是x作为变量名,它对我没有任何意义,我会选择o (对象)allTasks时,您将arr作为累加器传递,但它不是数组,而是一个对象,因此您可以/应该在那里使用o[...[dateConvert], ...valueConvert];等效于[dateConvert, ...valueConvert];,您可能希望更多地使用扩展运算符。get p1 p2 value是一个非常现代的评论,今天确实如此,因为任务确实只包含p1和p2,但是当任务变得新的或改变的时候,这个评论将变得毫无价值,请考虑像group all tasks properties这样的东西。allTasks.reduce((o, task)而不是allTasks.reduce((arr, item)如果你接受了所有这些,我会反对这个提议;
function convertData(data){
let dateConvert = data.filter(o => new Date(o.time)).map(o => {
const date = new Date(o.time);
return `${date.getFullYear()}-${ date.getMonth() + 1}-1`;
});
dateConvert = ["x", ...dateConvert];
let allTasks = data.flatMap(x => x.tasks);
//Group all task properties
const valueConvert = Object.values(allTasks.reduce((o, task) => {
o[task.key] = o[task.key] || [task.key];
o[task.key].push(task.value);
return o;
}, {}));
return [dateConvert, ...valueConvert];
}
const data2 = [
{
time: "2020-7",
tasks: [
{
key: "p1",
value: 15
},
{
key: "p2",
value: 13
},
]
},
{
time: "2020-8",
tasks: [
{
key: "p1",
value: 16
},
{
key: "p2",
value: 19
},
]
},
{
time: "2020-9",
tasks: [
{
key: "p1",
value: 12
},
{
key: "p2",
value: 93
},
]
}
];
console.log(convertData(data2));发布于 2020-09-04 14:16:10
你有
valueConvert = Object.values(allTasks.reduce((arr, item) => {
arr[item.key] = arr[item.key] || [item.key];
arr[item.key].push(item.value);
return arr;
}, {}));这在某种程度上是基于观点的,但在这种情况下,我建议使用避免减少,在这种情况下,累加器在所有迭代过程中都是相同的对象。关于Chrome的一些开发人员的视频,请参阅上面的链接,更详细地了解为什么这不是最好的想法。简而言之,虽然reduce是解决问题的一种可能方法,但它不必要地冗长,与普通循环相比,它可能有些混乱(特别是对于您的代码读者可能不太熟悉reduce);这是不必要的复杂。不要觉得必须在任何可能的地方使用数组方法(即使使用它表明您知道如何使用.reduce)。
您可以将其改为:
const tasksByKey = {};
for (const { key, value } of arr) {
tasksByKey[key] = tasksByKey[key] || [key];
tasksByKey[key].push(value);
}
const valueConvert = Object.values(tasksByKey);你经常使用let。如果可能的话,对总用const来说最好--当您一眼就知道某个特定的变量名称将永远不会被重新分配时,这会使代码更容易阅读和推理。考虑一下使用链接器,如果您还没有这样做的话--它可以使代码样式更加一致和可读性更强,并且可以减少bug。
同样,如果不需要重新分配变量名,请考虑避免这样做。而不是
dataConvert = [...[dateConvert], ...valueConvert];你可能会用
const datesAndValues = [dateConvert, ...valueConvert];记住,.flatMap是一个非常新的方法--如果这段代码是在一个面向公众的网站上运行的,那么一定要包括聚脂填充。(Object.values只在ES2017中正式使用,所以您可能也需要一个多填充)
https://codereview.stackexchange.com/questions/248907
复制相似问题