#javascript #typescript #ecmascript-6 #lodash
#javascript #typescript #ecmascript-6 #Lodash
Вопрос:
У меня есть объект с сгруппированными данными, сопоставленными с помощью функции Lodash groupBy, какой был бы наилучший способ выполнить итерацию по коллекции и получить следующую информацию:
- totalProductNumber,
- totalProductSum = Сумма(productsNumberInGroup * цена)
- productsNumberPerGroup
Таким образом, результат может быть
let result = {
totalProductNumber: 8,
totalProductSum: 17,
productsNumberPerGroup: [{1:2}, {2:3}, {3:3}] // or sth. like this
}
interface IProduct {
name: string;
color: string;
price: string;
id: number
}
const products = {
"1": [{
"name": "Jim",
"color": "blue",
"price": 1,
"id": 1
},
{
"name": "Jim",
"color": "blue",
"price": 1,
"id": 1
}
],
"2": [{
"name": "Eddie",
"color": "green",
"price": 2,
"id": 2
},
{
"name": "Eddie",
"color": "green",
"price": 2,
"id": 2
},
{
"name": "Eddie",
"color": "green",
"price": 2,
"id": 2
}
],
"3": [{
"name": "Ela",
"color": "pink",
"price": 3,
"id": 3
},
{
"name": "Ela",
"color": "pink",
"price": 3,
"id": 3
},
{
"name": "Ela",
"color": "pink",
"price": 3,
"id": 3
}
]
}
Я предполагаю использовать Object.entries или Object.values
let totalSum: number;
let totalPrices: number[];
Object.values(products)
.map((prod) => {
(prod as IProduct[]).map((p) => {
this.totalPrices.push(Number(p.price)); // here getting Cannot read property 'push' of undefined
});
});
Комментарии:
1. Вы только объявили totalPrices, вы не присвоили ему значение. Попробуйте присвоить ему пустой массив.
Ответ №1:
С изменяемым стилем
interface IProduct {
name: string
color: string
price: number
id: number
}
type Products = Record<string, IProduct[]>
const products: Products = { ... }
let totalProductNumber = 0
let totalProductSum = 0
let productsNumberPerGroup: [string, number][] = []
Object.entries(products).map(([grpId, grpProducts]) => {
totalProductNumber = totalProductNumber grpProducts.length
totalProductSum = totalProductSum grpProducts.reduce((acc, curr) => acc curr.price, 0)
productsNumberPerGroup = [...productsNumberPerGroup, [grpId, grpProducts.length]]
})
console.log(totalProductNumber) // 8
console.log(totalProductSum) // 17
console.log(productsNumberPerGroup) //[ [ '1', 2 ], [ '2', 3 ], [ '3', 3 ] ]
С неизменяемым стилем
type Result = [
totalProductNumber: number,
totalProductSum: number,
productsNumberPerGroup: [string, number][]
]
const initial: Result = [0, 0, []]
const [totalNum, totalSum, prdPerGrp] = Object.entries(products).reduce<Result>(
([num, sum, perGrp], [grpId, grpProducts]) => {
return [
num grpProducts.length,
sum grpProducts.reduce((acc, curr) => acc curr.price, 0),
[...perGrp, [grpId, grpProducts.length]]
]
},
initial
)
console.log(totalNum) // 8
console.log(totalSum) // 17
console.log(prdPerGrp) // [ [ '1', 2 ], [ '2', 3 ], [ '3', 3 ] ]
Ответ №2:
Вы должны сделать два изменения
let totalPrices: number[];
Для
let totalPrices: number[] = [];
Еще одно изменение в интерфейсе
interface IProduct {
name: string;
color: string;
price: string;
id: number
}
изменить
price: string;
Для
price: number;