繁体   English   中英

在对象数组中合并两个对象

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM