我试图根据选定的键对对象值求和,这些键在数组的每个对象中都可用。我的问题是如何处理percentage rate
。在下面的代码示例中,satisfaction_rate
应该具有48
。
我的输出应该是:
{
'students' : 87,
'books': 32,
'satisfaction_rate': 48
}
const myData = [
{
'students' : 30,
'books': 10,
'satisfaction_rate': "60%",
'returning_students': 14
}, {
'students' : 25,
'books': 8,
'satisfaction_rate': "45%",
'returning_students': 14
}, {
'students' : 32,
'books': 14,
'satisfaction_rate': "39%",
'returning_students': 19
}
];
const keysToConsider = ['students', 'books', 'satisfaction_rate'];
function getSumOrAvgValuesOfKeys(data){
const obj = {};
let val = 0;
keysToConsider.forEach(el => {
data.forEach(element => {
if (typeof(element[el] === 'string')) {
val += parseInt(element[el], 10);
} else {
val += element[el];
}
});
obj[el] = val;
// Reset value
val = 0;
});
return obj;
}
console.log(getSumOrAvgValuesOfKeys(myData));
答案 0 :(得分:5)
您可以使用reduce
方法,然后在最后一次迭代中为值是字符串类型的每个元素计算平均值。
const myData = [{"students":30,"books":10,"satisfaction_rate":"60%","returning_students":14},{"students":25,"books":8,"satisfaction_rate":"45%","returning_students":14},{"students":32,"books":14,"satisfaction_rate":"39%","returning_students":19}]
const keys = ['students', 'books', 'satisfaction_rate'];
const result = myData.reduce((r, e, i, a) => {
keys.forEach(k => r[k] = (r[k] || 0) + parseInt(e[k]));
if(!a[i + 1]) Object.keys(e)
.filter(k => typeof e[k] == 'string')
.forEach(k => r[k] /= myData.length)
return r;
}, {})
console.log(result)
答案 1 :(得分:1)
您可能还有另一个要对键进行平均的数组,在准备求和结果之后,您只能计算这些键的平均值。
const myData = [{
'students': 30,
'books': 10,
'satisfaction_rate': "60%",
'returning_students': 14
}, {
'students': 25,
'books': 8,
'satisfaction_rate': "45%",
'returning_students': 14
}, {
'students': 32,
'books': 14,
'satisfaction_rate': "39%",
'returning_students': 19
}];
const keysToConsider = ['students', 'books', 'satisfaction_rate'];
let keysWithPercent = ['satisfaction_rate'];
const summed = myData.reduce((result, item) => {
keysToConsider.forEach(k => {
if (!result[k]) {
result[k] = 0;
}
let v = parseInt(item[k], 10);
result[k] += v;
});
return result;
}, {});
keysWithPercent.forEach(k => {
summed[k] = summed[k] / myData.length;
})
console.log(summed);
答案 2 :(得分:1)
您可以通过采用以前的值或默认值来减少对象。对于百分比值,请用三分之一进行求和。
var data = [{ students: 30, books: 10, satisfaction_rate: "60%", returning_students: 14 }, { students: 25, books: 8, satisfaction_rate: "45%", returning_students: 14 }, { students: 32, books: 14, satisfaction_rate: "39%", returning_students: 19 }],
result = data.reduce((r, { students, books, satisfaction_rate }, _, a) => ({
students: (students || 0) + students,
books: (r.books || 0) + books,
satisfaction_rate: (r.satisfaction_rate || 0) + satisfaction_rate.slice(0, -1) / a.length
}), {});
console.log(result);
带有动态键列表
var data = [{ students: 30, books: 10, satisfaction_rate: "60%", returning_students: 14 }, { students: 25, books: 8, satisfaction_rate: "45%", returning_students: 14 }, { students: 32, books: 14, satisfaction_rate: "39%", returning_students: 19 }],
keys = ['students', 'books', 'satisfaction_rate'],
result = data.reduce((r, o, _, a) =>
Object.assign(
...keys.map(k =>
({ [k]: (r[k] || 0) + (o[k].toString().endsWith('%')
? o[k].slice(0, -1) / a.length
: o[k])
}))
),
{}
);
console.log(result);
答案 3 :(得分:0)
恕我直言,您可以尝试使用reduce
完成以下操作:
var myData = [{ students: 30, books: 10, satisfaction_rate: "60%", returning_students: 14 }, { students: 25, books: 8, satisfaction_rate: "45%", returning_students: 14 }, { students: 32, books: 14, satisfaction_rate: "39%", returning_students: 19 }]
var result = myData.reduce((accum, { students, books, satisfaction_rate }, idx, arr) => {
accum["students"] ? (accum["students"] += students) : (accum["students"] = students);
accum["books"] ? (accum["books"] += books) : (accum["books"] = books);
accum["satisfaction_rate"] ? (accum["satisfaction_rate"] += parseInt(satisfaction_rate)) : (accum["satisfaction_rate"] = parseInt(satisfaction_rate));
if (idx === arr.length - 1) {
accum["satisfaction_rate"] = accum["satisfaction_rate"] / arr.length
}
return accum;
}, {});
console.log(result);
答案 4 :(得分:0)
更通用的解决方案是指定您要如何减少 keysToConsider
对象中的每个键。您可以使用SUM,AVG,MIN,MAX甚至是标准偏差等更复杂的参数来减少它们。
在这种情况下,我会将您的keysToConsider
更改为对象而不是数组:
const myData = [{
'students': 30,
'books': 10,
'satisfaction_rate': "60%",
'returning_students': 14
}, {
'students': 25,
'books': 8,
'satisfaction_rate': "45%",
'returning_students': 14
}, {
'students': 32,
'books': 14,
'satisfaction_rate': "39%",
'returning_students': 19
}];
keysToConsider = {
'students': sum,
'books': sum,
'satisfaction_rate': avg
}
function reduceValuesOfKeys(data) {
const obj = {};
let val = 0;
for (var p in keysToConsider) {
var reduce = keysToConsider[p];
obj[p] = reduce(data, p);
}
return obj;
}
function sum(data, property) {
var val = 0;
data.forEach(element => {
if (typeof(element[property] === 'string')) {
val += parseInt(element[property], 10);
} else {
val += element[property];
}
});
return val;
}
function avg(data, property) {
var val = 0;
data.forEach(element => {
if (typeof(element[property] === 'string')) {
val += parseInt(element[property], 10);
} else {
val += element[property];
}
});
return val / data.length;
}
console.log(reduceValuesOfKeys(myData));
如果将来需要添加其他reduce函数,会更容易。