[英]Merge two objects inside array of objects
我有以下数组:
[
{
"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和日期合并对象并计算平均标记,因此我可以拥有以下内容:
[
{
"idItem": "5d656f10394d6524c821f1b1",
"mark": 3.5,
"date": "2018-11-27T00:00:00.000Z"
},
{
"idItem": "5d656f10394d6524c821f1b1",
"mark": 1.5,
"date": "2018-12-27T00:00:00.000Z"
}
]
尝试这个:
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,
})
);
可能不是性能最高的,但它可以工作。 首先,我们获得一组所有id和date的组合,然后过滤每个组合的输入。 然后,对于每个组,我们将日期和ID复制到结果中,并减少条目以获得平均值。
如果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);
我正在使用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 }]
}, [])
首先,我将声明在此示例中将使用的数组:
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));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.