Использование reduce
с динамическими c ключами с Typescript может быть уродливым и, возможно, неуместно даже в Javascript при создании одного объекта. Попробуйте создать объект, в который вы помещаете данные, вне l oop - тот, чьи свойства являются именами (High, et c), а значения - числовыми массивами. Pu sh в массив чисел на каждой итерации (нажимая 0, если свойство не существует), сначала создавая свойство с массивом, если необходимо. После зацикливания превратите объект в массив объектов:
// compliant with noImplicitAny and strict options
type DataItem = {
time: string;
sum: number;
valueObj?: {
High: number;
Medium: number;
Low: number;
}
};
const sampleData: DataItem[] = [
{ valueObj: { High: 4, Low: 5, Medium: 7 } , time: "1571372233234" , sum: 16 },
{ valueObj: { High: 5, Low: 3, Medium : 1 }, time: "1571372233234" , sum: 9},
{ time: "14354545454", sum: 0},
{ time: "14354545454", sum: 0}
];
const keys = ['High', 'Low', 'Medium'] as const;
const grouped = {} as { [key: string]: number[] };
for (const item of sampleData) {
for (const key of keys) {
if (!grouped[key]) {
grouped[key] = [];
}
grouped[key].push(item.valueObj ? item.valueObj[key] : 0);
}
}
const output = Object.entries(grouped).map(([name, data]) => ({ name, data }));
Скомпилированный вывод:
"use strict";
const sampleData = [
{ valueObj: { High: 4, Low: 5, Medium: 7 }, time: "1571372233234", sum: 16 },
{ valueObj: { High: 5, Low: 3, Medium: 1 }, time: "1571372233234", sum: 9 },
{ time: "14354545454", sum: 0 },
{ time: "14354545454", sum: 0 }
];
const keys = ['High', 'Low', 'Medium'];
const grouped = {};
for (const item of sampleData) {
for (const key of keys) {
if (!grouped[key]) {
grouped[key] = [];
}
grouped[key].push(item.valueObj ? item.valueObj[key] : 0);
}
}
const output = Object.entries(grouped).map(([name, data]) => ({ name, data }));
console.log(output);
Если клавиша valueObj
является динамической c, она становится намного ужаснее. Лучшее, что я мог выяснить, было, при переборе элемента массива, если у него есть собственное свойство ключа объекта, то утверждать, что элемент массива имеет тип { [possibleKeyForObj: string]: { [key: string]: number } }
, что позволяет вам получить доступ к вложенному свойству:
const formResult = (
sampleData: object[],
possibleKeyForObj: string,
keys: string[],
) => {
const grouped = Object.fromEntries(keys.map(key => [key, []]));
for (const item of sampleData) {
for (const key of keys) {
grouped[key].push(
item.hasOwnProperty(possibleKeyForObj)
? (item as { [possibleKeyForObj: string]: { [key: string]: number } })[possibleKeyForObj][key]
: 0,
);
}
}
const output = Object.entries(grouped).map(([name, data]) => ({ name, data }));
console.log(output);
};
formResult(
[
{ valueObj: { High: 4, Low: 5, Medium: 7 }, time: '1571372233234', sum: 16 },
{ valueObj: { High: 5, Low: 3, Medium: 1 }, time: '1571372233234', sum: 9 },
{ time: '14354545454', sum: 0 },
{ time: '14354545454', sum: 0 },
],
'valueObj',
['High', 'Low', 'Medium'],
);