我有以下数组:
[
{
"idItem": "5d656f10394d6524c821f1b1",
"mark": 5,
"date": "2018-11-27T00:00:00.000Z"
},
{
"idItem": "5d656f10394d6524c821f1b1",
"mark": 2,
"date": "2018-11-27T00:00:00.000Z"
},
{
"idItem": "5d656f10394d6524c821f1b1",
"mark": 1,
"date": "2018-12-27T00:00:00.000Z"
},
{
"idItem": "5d656f10394d6524c821f1b1",
"mark": 2,
"date": "2018-12-27T00:00:00.000Z",
}
]
我想基于 idItem 和 date 合并对象并计算平均标记,这样我就可以得到以下内容:
[
{
"idItem": "5d656f10394d6524c821f1b1",
"mark": 3.5,
"date": "2018-11-27T00:00:00.000Z"
},
{
"idItem": "5d656f10394d6524c821f1b1",
"mark": 1.5,
"date": "2018-12-27T00:00:00.000Z"
}
]
答案 0 :(得分:1)
尝试一下:
const input = [
{ idItem: "5d656f10394d6524c821f1b1", mark: 5, date: "2018-11-27T00:00:00.000Z" },
{ idItem: "5d656f10394d6524c821f1b1", mark: 2, date: "2018-11-27T00:00:00.000Z" },
{ idItem: "5d656f10394d6524c821f1b1", mark: 1, date: "2018-12-27T00:00:00.000Z" },
{ idItem: "5d656f10394d6524c821f1b1", mark: 2, date: "2018-12-27T00:00:00.000Z" }
];
const ids = new Set(input.map(e => `${e.idItem} ${e.date}`));
const grouped = [...ids].map(id => input.filter(
e => `${e.idItem} ${e.date}` === id
)).map(
group => ({
...group[0],
mark: group.reduce((acc, cur) => cur.mark + acc, 0) / group.length,
})
);
您可以看到结果已注销here
可能不是性能最高的,但是可以。首先,我们获得一组所有id和date的组合,然后过滤每个组合的输入。然后,对于每个组,我们将日期和ID复制到结果中,并减少条目以获得平均值。
答案 1 :(得分:1)
如果id和date字符串中没有逗号(,
),则可以使用此解决方案,我首先生成一个对象,其中键是id和日期的串联,并且这些值是具有具有键的ID和日期以及其标记之和的元素数量的对象,然后该对象将用于构造所需的数组:
var arr = [
{ "idItem": "5d656f10394d6524c821f1b1", "mark": 5, "date": "2018-11-27T00:00:00.000Z" },
{ "idItem": "5d656f10394d6524c821f1b1", "mark": 2, "date": "2018-11-27T00:00:00.000Z" },
{ "idItem": "5d656f10394d6524c821f1b1", "mark": 1, "date": "2018-12-27T00:00:00.000Z" },
{ "idItem": "5d656f10394d6524c821f1b1", "mark": 2, "date": "2018-12-27T00:00:00.000Z" }
];
var obj = {};
arr.forEach((o) => {
var k = o.idItem + ',' + o.date;
if (obj.hasOwnProperty(k)) {
obj[k].s += o.mark;
obj[k].n += 1;
} else {
obj[k] = {s: o.mark, n: 1};
}
});
var result = [];
Object.keys(obj).forEach((k) => {
var p = k.split(',');
result.push({idItem: p[0], date: p[1], mark: obj[k].s / obj[k].n})
});
console.log(result);
答案 2 :(得分:1)
我正在使用lodash groupBy。
Object.entries(_.groupBy([
{
"idItem": "5d656f10394d6524c821f1b1",
"mark": 5,
"date": "2018-11-27T00:00:00.000Z"
},
{
"idItem": "5d656f10394d6524c821f1b1",
"mark": 2,
"date": "2018-11-27T00:00:00.000Z"
},
{
"idItem": "5d656f10394d6524c821f1b1",
"mark": 1,
"date": "2018-12-27T00:00:00.000Z"
},
{
"idItem": "5d656f10394d6524c821f1b1",
"mark": 2,
"date": "2018-12-27T00:00:00.000Z",
}
], e => `${e.idItem}_${e.date}`)).reduce((acc, [key, value]) => {
const mark = value.reduce((sum, el) => sum + el.mark, 0) / value.length
const [idItem, date] = key.split('_')
return [...acc, { idItem, date, mark }]
}, [])
答案 3 :(得分:0)
首先,我将声明在此示例中将使用的数组:
var array = [
{
"idItem": "5d656f10394d6524c821f1b1",
"mark": 5,
"date": "2018-11-27T00:00:00.000Z"
},
{
"idItem": "5d656f10394d6524c821f1b1",
"mark": 2,
"date": "2018-11-27T00:00:00.000Z"
},
{
"idItem": "5d656f10394d6524c821f1b1",
"mark": 1,
"date": "2018-12-27T00:00:00.000Z"
},
{
"idItem": "5d656f10394d6524c821f1b1",
"mark": 2,
"date": "2018-12-27T00:00:00.000Z",
}
];
这就是这种情况:我有一个程序可以工作,但另一个实现却几乎有效。我将从一个有效的程序开始,它使用alasql
库:
要加载依赖项,请使用以下<script>
标签:
<script src="https://cdn.jsdelivr.net/npm/alasql@0.4">
实施:
var newArray = alasql('SELECT idItem, AVG([mark]) AS [mark], date AS [date]
FROM ? GROUP BY date',[array]);
console.log(JSON.stringify(newArray));
下一个程序仅计算不考虑日期的所有ID的平均值(因此得出的平均值为2.5)。也许有人可以弄清楚如何正确运行该程序并编辑我的答案:
var sum = {};
for(var i = 0; i < array.length; i++) {
var ele = array[i];
if (!sum[ele.idItem]) {
sum[ele.idItem] = {};
sum[ele.idItem]["sum"] = 0;
sum[ele.idItem]["count"] = 0;
}
sum[ele.idItem]["sum"] += ele.mark;
sum[ele.idItem]["count"]++;
}
var result = [];
for (var idItem in sum) {
result.push({idItem: idItem, mark: sum[idItem]["sum"] / sum[idItem]["count"]});
}
console.log(JSON.stringify(result));