我正在嘗試找到一種有效的方法來對 javascript 中物件陣列中的資料進行分組和求和。我愿意為此使用 lodash 作為庫,并研究了其他類似的問題,但不完全是我想要的。在這里,我想創建一個通用函式,它接受一個資料陣列、一個要分組的欄位陣列和一個要求和的欄位陣列。
以這個示例物件陣列為例:
const data= [
{
contintent:'North America',
country:'us',
state:'ma',
population: 1567986,
fee: 24343
},
{
contintent:'North America',
country:'us',
state:'tx',
population: 7567986,
fee: 119343
},
{
contintent:'North America',
country:'ca',
state:'on',
population: 467986,
fee: 3343
},
{
contintent:'North America',
country:'ca',
state:'qb',
population: 1268986,
fee: 54248
},
{
contintent:'Europe',
country:'ge',
state:'mc',
population: 4268986,
fee: 97333
},
{
contintent:'Europe',
country:'it',
state:'fl',
population: 978353,
fee: 248
},
]
我想創建一個看起來像這樣的函式:
const GroupByFunction =(array, groupbyFields, sumFields) {
}
如果我用這些欄位來呼叫它 const result1 = GroupByFuntion(data,['continent'],['population','fee'])
結果看起來像這樣,其中 popSum 和 popFee 只是組成屬性名稱來保存總和值:
const result1 = [
{
contintent:'North America',
popSum:10872944,
popfee:201277,
data: [
{
contintent:'North America',
country:'us',
state:'ma',
population: 1567986,
fee: 24343
},
{
contintent:'North America',
country:'us',
state:'tx',
population: 7567986,
fee: 119343
},
{
contintent:'North America',
country:'ca',
state:'on',
population: 467986,
fee: 3343
},
{
contintent:'North America',
country:'ca',
state:'qb',
population: 1268986,
fee: 54248
},
]
},
{
contintent:'Europe',
popSum: 5247339,
feeSum:97581,
data: [
{
contintent:'Europe',
country:'ge',
state:'mc',
population: 4268986,
fee: 97333
},
{
contintent:'Europe',
country:'it',
state:'fl',
population: 978353,
fee: 248
},
]
}
]
但是,我也可以通過這樣的鍵傳遞多個組:
const result2 = GroupByFuntion(data,['continent','country'],['population','fee'])
結果將如下所示(popSum 和 popFee 只是垃圾資料占位符,它們將是陣列中的總和值):
const result2 = [
{
contintent:'North America',
popSum:10872944,
popfee:201277,
country: [
{
country:'us',
popSum: 2423423,
popFee: 2323,
data: [
{
contintent:'North America',
country:'us',
state:'ma',
population: 1567986,
fee: 24343
},
{
contintent:'North America',
country:'us',
state:'tx',
population: 7567986,
fee: 119343
},
]
},
{
country:'ca',
popSum: 54443,
popFee: 34324,
data: [
{
contintent:'North America',
country:'ca',
state:'on',
population: 467986,
fee: 3343
},
{
contintent:'North America',
country:'ca',
state:'qb',
population: 1268986,
fee: 54248
},
]
}
]
},
{
contintent:'Europe',
popSum: 3432423,
popFee: 3432,
country: [
{
country: 'gb',
popSum: 32432,
popFee: 564,
data: [
{
contintent:'Europe',
country:'ge',
state:'mc',
population: 4268986,
fee: 97333
},
]
},
{
country: 'it',
popSum: 89332,
popFee: 8932,
data: [
{
contintent:'Europe',
country:'ge',
state:'mc',
population: 4268986,
fee: 97333
},
]
},
]
},
]
這是否可以使用 lodash 中的 _groupBy 和 _sumBy 函式或其他方式?
uj5u.com熱心網友回復:
這似乎達到了你想要的:
const data = [
{
continent:'North America',
country:'us',
state:'ma',
population: 1567986,
fee: 24343
},
{
continent:'North America',
country:'us',
state:'tx',
population: 7567986,
fee: 119343
},
{
continent:'North America',
country:'ca',
state:'on',
population: 467986,
fee: 3343
},
{
continent:'North America',
country:'ca',
state:'qb',
population: 1268986,
fee: 54248
},
{
continent:'Europe',
country:'ge',
state:'mc',
population: 4268986,
fee: 97333
},
{
continent:'Europe',
country:'it',
state:'fl',
population: 978353,
fee: 248
},
]
const groupBy = (rawArray, groupbyFields, sumFields) => {
const field = groupbyFields[0]
const fieldValues = new Set()
rawArray.forEach(e => fieldValues.add(e[field]))
const array = []
for (const fieldValue of fieldValues.values()) {
let data = rawArray.filter(e => e[field] === fieldValue)
if (groupbyFields.length > 1) {
data = groupBy(data, groupbyFields.slice(1), sumFields)
}
const obj = { data }
sumFields.forEach(sumField => {
const sumFieldName = `${ sumField }Sum`
obj[sumFieldName] = data.map(e => e[sumField] ?? e[sumFieldName] ?? 0).reduce((g, c) => g c, 0)
})
obj[field] = fieldValue
array.push(obj)
}
return array
}
console.log(JSON.stringify(groupBy(data, [ 'continent', 'country' ],[ 'population', 'fee' ]), null, ' '))
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/533213.html
