function objectAverage(arr, ignore) {
const helper = new Map()
const res = {}
function handleDataToMap(data, parent) {
// 需要忽略的key
if (ignore && parent.length && parent[parent.length - 1] === ignore) {
return
}
const dataType = typeof data
if (data !== null && dataType === 'object') {
for (const key in data) {
if (Object.hasOwnProperty.call(data, key)) {
handleDataToMap(data[key], [...parent, key]);
}
}
} else if (dataType === 'number') {
const key = parent.join('|')
let val = helper.get(key)
if (!val) {
val = {
value: 0,
count: 0,
}
helper.set(key, val)
}
val.value += data
val.count++
}
}
if (!arr?.length) {
return null
}
for (const item of arr) {
handleDataToMap(item, [])
}
for (const [k, v] of helper.entries()) {
setIn(res, k.split('|'), parseFloat((v.value / v.count).toFixed(2)))
}
return res
}
function setIn(obj, keys, value) {
const len = keys.length
if (len === 0) {
return
}
const key = keys.shift()
if (len === 1) {
obj[key] = value
} else {
if (!Object.prototype.hasOwnProperty.call(obj, key)) {
obj[key] = {}
}
setIn(obj[key], keys, value)
}
}
const testListWithNestedDicts = [
{
"studentId": 1,
"age": 7,
"height": 2,
"weight": 3,
"scores": {
"spanish": 80,
"mathematics": 90,
"english": 100,
"pe": {
"run": 85,
"jump": 95
}
}
},
{
"studentId": 2,
"age": 8,
"height": 4,
"weight": 6,
"scores": {
"spanish": 90,
"mathematics": 90,
"english": 80,
"pe": {
"run": 90,
"jump": 90
}
}
},
{
"studentId": 3,
"age": 7,
"height": 3,
"weight": 6,
"scores": {
"spanish": 86,
"mathematics": 90,
"english": 75,
"pe": {
"run": 65,
"jump": 90
}
}
}
]
console.log(objectAverage(testListWithNestedDicts, 'studentId'))
console