使用 javascript 筛选和计算来自相同 table 的对象的属性
Filter and calculate the properties of objects from the same table using javascript
我希望我的问题不会在 SO 中问得太多。
我有一个包含 3 个对象的数组,例如:
const objStart1 = {
'user': 1,
'score': 15,
'date': 'Monday'
}
const objStart2 = {
'user': 1,
'score': 7,
'date': 'Friday'
}
const objStart3 = {
'user': 2,
'score': 5,
'date': 'Monday'
}
我想按日期分组,然后按天计算分数的平均值(并删除用户)和 return 一个新的对象数组,例如:
const objStart1 = {
'average': 10,
'date': 'Monday'
}
const objStart2 = {
'average': 7,
'date': 'Friday'
}
貌似可以用filter + reduce,但是效果很差...有什么好的解决办法吗?
提前致谢。
这应该可以解决问题。
我将您的项目放入实际数组中,并将 Date
替换为 date
。
const input = [
{
'user': 1,
'score': 15,
'date': 'Monday'
},
{
'user': 1,
'score': 7,
'date': 'Friday'
},
{
'user': 2,
'score': 5,
'date': 'Monday'
},
]
const sumList = input.reduce((acc, current) => {
if(!acc.find(obj => obj.date === current.date)) acc.push({date: current.date, sum: 0, count: 0})
const currCounter = acc.find(obj => obj.date === current.date)
currCounter.sum += current.score
currCounter.count++
return acc
}, [])
.map(({date, sum, count}) => ({ date, average: sum/count }))
console.log(sumList)
const objStart1 = {
'user': 1,
'score': 15,
'date': 'Monday'
}
const objStart2 = {
'user': 1,
'score': 7,
'date': 'Friday'
}
const objStart3 = {
'user': 2,
'score': 5,
'date': 'Monday'
}
const objs = [objStart1, objStart2, objStart3];
let avgForDate = {};
avgForDate = objs.reduce((res, current) => {
const oldInfo = res[current.date] ?? {
count: 0,
scoreSum: 0,
};
const newInfo = {
count: oldInfo.count + 1,
scoreSum: oldInfo.scoreSum + current.score,
};
res[current.date] = newInfo;
return res;
}, avgForDate);
for(const info in avgForDate) {
console.log({
date: info,
avg: avgForDate[info].scoreSum / avgForDate[info].count,
});
}
您可以执行以下操作:
(请注意我将密钥 Date
更改为 date
)。
const objStart1 = { 'user': 1, 'score': 15, 'date': 'Monday' }
const objStart2 = { 'user': 1, 'score': 7, 'date': 'Friday' }
const objStart3 = { 'user': 2, 'score': 5, 'date': 'Monday' }
function getAverageScoreByDate(...items) {
const dates = items.reduce((previousValue, currentValue) => {
if(previousValue.includes(currentValue.date)) {
return previousValue
};
return [
...previousValue,
currentValue.date,
]
}, []);
const averageScoresByDate = dates.map(date => {
const itemsByDate = items.filter(item => item.date === date);
const average = itemsByDate.reduce((previousValue, currentValue) => previousValue += currentValue.score, 0);
return {
date,
average
}
});
return averageScoresByDate;
};
console.log(getAverageScoreByDate(objStart1, objStart2, objStart3));
如果您有超过 3 个对象,它将允许任意数量的参数。
出于演示的目的,我已经分离了一些位,但可以链接数组方法。
另一种写法。
const arr=[ { 'user': 1, 'score': 15, 'date': 'Monday' }, { 'user': 1, 'score': 7, 'date': 'Friday' }, { 'user': 2, 'score': 5, 'date': 'Monday' } ]
const result = arr.reduce((acc, curr, i)=>{
if(!acc.find((el)=>el.date==curr.date)){
acc.push({date: curr.date, score: curr.score, count: 1})
return acc
}
acc.map(el=>el.date===curr.date?(el.score+=curr.score,el.count+=1,el):el)
return acc
},[])
console.log(result.map((el)=>({average: el.score/el.count, date: el.date})))
我希望我的问题不会在 SO 中问得太多。
我有一个包含 3 个对象的数组,例如:
const objStart1 = {
'user': 1,
'score': 15,
'date': 'Monday'
}
const objStart2 = {
'user': 1,
'score': 7,
'date': 'Friday'
}
const objStart3 = {
'user': 2,
'score': 5,
'date': 'Monday'
}
我想按日期分组,然后按天计算分数的平均值(并删除用户)和 return 一个新的对象数组,例如:
const objStart1 = {
'average': 10,
'date': 'Monday'
}
const objStart2 = {
'average': 7,
'date': 'Friday'
}
貌似可以用filter + reduce,但是效果很差...有什么好的解决办法吗?
提前致谢。
这应该可以解决问题。
我将您的项目放入实际数组中,并将 Date
替换为 date
。
const input = [
{
'user': 1,
'score': 15,
'date': 'Monday'
},
{
'user': 1,
'score': 7,
'date': 'Friday'
},
{
'user': 2,
'score': 5,
'date': 'Monday'
},
]
const sumList = input.reduce((acc, current) => {
if(!acc.find(obj => obj.date === current.date)) acc.push({date: current.date, sum: 0, count: 0})
const currCounter = acc.find(obj => obj.date === current.date)
currCounter.sum += current.score
currCounter.count++
return acc
}, [])
.map(({date, sum, count}) => ({ date, average: sum/count }))
console.log(sumList)
const objStart1 = {
'user': 1,
'score': 15,
'date': 'Monday'
}
const objStart2 = {
'user': 1,
'score': 7,
'date': 'Friday'
}
const objStart3 = {
'user': 2,
'score': 5,
'date': 'Monday'
}
const objs = [objStart1, objStart2, objStart3];
let avgForDate = {};
avgForDate = objs.reduce((res, current) => {
const oldInfo = res[current.date] ?? {
count: 0,
scoreSum: 0,
};
const newInfo = {
count: oldInfo.count + 1,
scoreSum: oldInfo.scoreSum + current.score,
};
res[current.date] = newInfo;
return res;
}, avgForDate);
for(const info in avgForDate) {
console.log({
date: info,
avg: avgForDate[info].scoreSum / avgForDate[info].count,
});
}
您可以执行以下操作:
(请注意我将密钥 Date
更改为 date
)。
const objStart1 = { 'user': 1, 'score': 15, 'date': 'Monday' }
const objStart2 = { 'user': 1, 'score': 7, 'date': 'Friday' }
const objStart3 = { 'user': 2, 'score': 5, 'date': 'Monday' }
function getAverageScoreByDate(...items) {
const dates = items.reduce((previousValue, currentValue) => {
if(previousValue.includes(currentValue.date)) {
return previousValue
};
return [
...previousValue,
currentValue.date,
]
}, []);
const averageScoresByDate = dates.map(date => {
const itemsByDate = items.filter(item => item.date === date);
const average = itemsByDate.reduce((previousValue, currentValue) => previousValue += currentValue.score, 0);
return {
date,
average
}
});
return averageScoresByDate;
};
console.log(getAverageScoreByDate(objStart1, objStart2, objStart3));
如果您有超过 3 个对象,它将允许任意数量的参数。
出于演示的目的,我已经分离了一些位,但可以链接数组方法。
另一种写法。
const arr=[ { 'user': 1, 'score': 15, 'date': 'Monday' }, { 'user': 1, 'score': 7, 'date': 'Friday' }, { 'user': 2, 'score': 5, 'date': 'Monday' } ]
const result = arr.reduce((acc, curr, i)=>{
if(!acc.find((el)=>el.date==curr.date)){
acc.push({date: curr.date, score: curr.score, count: 1})
return acc
}
acc.map(el=>el.date===curr.date?(el.score+=curr.score,el.count+=1,el):el)
return acc
},[])
console.log(result.map((el)=>({average: el.score/el.count, date: el.date})))