I have a function written like so:
type ChartData = {
x?: number[],
y?: number[],
z?: number[],
};
const data = [{ x: 1, y: 2, z: 3 }, { x: 4, y: 7, z: 10 }];
const formattedData = data.reduce((acc, el) => {
Object.entries(el!).forEach(([k, v]) => {
acc = { ...acc, [k]: [...(acc[k as keyof ChartData] || []), v] };
});
return acc;
}, {} as ChartData);
This code does what I want, but I'm getting an eslint error: no-param-reassign
.
I know that I could disable the rule, but I wondered if there's a better way of writing this reduce callback so that I am not reassigning acc
.
CodePudding user response:
You can assign to acc[k]
directly:
const data = [{ x: 1, y: 2, z: 3 }, { x: 4, y: 7, z: 10 }];
const formattedData = data.reduce((acc, el) => {
Object.entries(el).forEach(([k, v]) => {
acc[k] = (acc[k] || []).concat(v);
});
return acc;
}, {});
console.log(formattedData);
More code but also more efficient (fewer allocations and copies):
const data = [{ x: 1, y: 2, z: 3 }, { x: 4, y: 7, z: 10 }];
const formattedData = data.reduce((acc, el) => {
Object.entries(el).forEach(([k, v]) => {
if (!acc[k]) {
acc[k] = [];
}
acc[k].push(v);
});
return acc;
}, {});
console.log(formattedData);
CodePudding user response:
This 'no-param-reassign' warning mean that you have modified the function params inside the function. So here maybe a workaround for this warning.
type ChartData = {
x?: number[],
y?: number[],
z?: number[],
};
const data = [{ x: 1, y: 2, z: 3 }, { x: 4, y: 7, z: 10 }];
const formattedData = data.reduce((acc, el) => {
let newAcc = { ...acc };
Object.entries(el!).forEach(([k, v]) => {
newAcc = { ...newAcc , [k]: [...(newAcc [k as keyof ChartData] || []), v] };
});
return newAcc ;
}, {} as ChartData);