我有這個物件陣列
const items = [
{
id: '121',
itemDate: '2022-04-28',
itemName: 'testname1',
itemCategory: 'Category A',
itemPrice: { price: '100', currency: 'GBP' },
createdBy: {
username: 'user1',
name: 'Name 1',
date: '2022-04-28T22:41:59',
},
},
{
id: '122',
itemDate: '2022-04-28',
itemName: 'testname2',
itemCategory: 'Category B',
itemPrice: { price: '100', currency: 'GBP' },
createdBy: {
username: 'user2',
name: 'Name 2',
date: '2022-04-28T22:42:44',
},
},
{
id: '122',
itemDate: '2022-04-28',
itemName: 'testname3',
itemCategory: 'Category C',
itemPrice: { price: '200', currency: 'GBP' },
createdBy: {
username: 'user2',
name: 'Name 2',
date: '2022-04-28T22:43:16',
},
},
]
我正在使用的代碼:
items.reduce(function (c, x) {
if (!c[x.createdBy.username])
c[x.createdBy.username] = {
username: x.createdBy.username,
total: 0,
}
c[x.createdBy.username].total = Number(x.itemPrice.price)
return c
}, [])
這部分給了我以下輸出:
items :>> [
user1: { username: 'user1', total: 100},
user2: { username: 'user2', total: 300}
]
所以我嘗試了這個來擺脫物件名稱:
let output = []
let totalSum = 0
for (const username in items) {
let temp = {
username: items[username].username,
total: items[username].total,
}
totalSum = totalSum items[username].total
output.push(temp)
}
output.push({ username: 'allUsers', total: totalSum })
return output
最終輸出是我現在想要的:
output :>> [
{ username: 'user1', total: 100 },
{ username: 'user2', total: 300 },
{ username: 'allUsers', total: 400}
]
我的兩個問題...
有沒有辦法更新該.reduce部分,以便我在開始時獲得一個沒有名稱的物件,而不必使用 for 回圈?
還有一種方法可以實作匯總所有總數的部分嗎?
謝謝
uj5u.com熱心網友回復:
代碼示例(無注釋/描述)
const groupAndAdd = arr => (
Object.values(
arr.reduce(
(acc, {createdBy : {username}, itemPrice: {price}}) => {
acc.allUsers ??= { username: 'allUsers', total: 0};
acc.allUsers.total = price;
if (username in acc) {
acc[username].total = price;
} else {
acc[username] = {username, total: price};
}
return acc;
},
{}
)
)
);
下面介紹的是實作預期目標的作業演示,并附有注釋/評論以幫助理解。
代碼片段
// method to group by user and sum prices
const groupAndAdd = arr => (
// extract the values from the intermediate result-object
Object.values(
arr.reduce( // generate result as object
(acc, {createdBy : {username}, itemPrice: {price}}) => {
// above line uses de-structuring to directly access username, price
// below uses logical nullish assignment to set-up "allUsers"
acc.allUsers ??= { username: 'allUsers', total: 0};
// accumulate the "price" to the all-users "total"
acc.allUsers.total = price;
// if "acc" (accumulator) has "username", simply add price to total
if (username in acc) {
acc[username].total = price;
} else {
// create an object for the "username" with initial total as "price"
acc[username] = {username, total: price};
}
// always return the "acc" accumulator for ".reduce()"
return acc;
},
{} // initially set the "acc" to empty object
)
) // if required, use ".sort()" to move the all-users to last position in array
);
const items = [{
id: '121',
itemDate: '2022-04-28',
itemName: 'testname1',
itemCategory: 'Category A',
itemPrice: {
price: '100',
currency: 'GBP'
},
createdBy: {
username: 'user1',
name: 'Name 1',
date: '2022-04-28T22:41:59',
},
},
{
id: '122',
itemDate: '2022-04-28',
itemName: 'testname2',
itemCategory: 'Category B',
itemPrice: {
price: '100',
currency: 'GBP'
},
createdBy: {
username: 'user2',
name: 'Name 2',
date: '2022-04-28T22:42:44',
},
},
{
id: '122',
itemDate: '2022-04-28',
itemName: 'testname3',
itemCategory: 'Category C',
itemPrice: {
price: '200',
currency: 'GBP'
},
createdBy: {
username: 'user2',
name: 'Name 2',
date: '2022-04-28T22:43:16',
},
},
];
console.log('group and add prices per user: ', groupAndAdd(items));
.as-console-wrapper { max-height: 100% !important; top: 0 }
解釋
添加到上述代碼段的行內注釋。
PS:如果您想為 stackoverflow 社區增加價值,
請考慮閱讀:回答我的問題后該怎么辦 謝謝!
uj5u.com熱心網友回復:
對于您的第一個問題,您正確地初始化為一個陣列,但您只使用了物件。有兩種方法可以做到這一點。
第一個選項
let something = items.reduce(function(c, x) {
if (!c[x.createdBy.username])
c[x.createdBy.username] = {
username: x.createdBy.username,
total: 0,
}
c[x.createdBy.username].total = Number(x.itemPrice.price)
return c
}, {});
something = Object.values(something);
第二種選擇
我正在考慮只使用推送,但似乎不可能,所以上面是唯一的選擇。
使用 push 是可能的,但是通過檢查 find 并更新正確的陣列元素會變得太復雜。
對于總結所有總數的第二個問題,您可以使用以下簡單語法:
const sum = arr.reduce((a, c) => a c, 0);
這是對數字陣列求和所需的最少代碼。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/468536.html
標籤:javascript 数组 目的
