代码之家  ›  专栏  ›  技术社区  ›  Ayoub k

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

  •  0
  • Ayoub k  · 技术社区  · 5 年前

    我有以下数组:

    [
        {
            "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",
        }
    ]
    

    我想合并对象基于 IDITENT 日期 然后计算平均分,这样我就可以得到:

    [
        {
            "idItem": "5d656f10394d6524c821f1b1",
            "mark": 3.5,
            "date": "2018-11-27T00:00:00.000Z"
        },
        {
            "idItem": "5d656f10394d6524c821f1b1",
            "mark": 1.5,
            "date": "2018-12-27T00:00:00.000Z"
        }
    ]
    
    4 回复  |  直到 5 年前
        1
  •  1
  •   Jasper Bernales    5 年前

    我在用洛达斯 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 }]
    }, [])
    
    
        2
  •  1
  •   Danny Buonocore DTM    5 年前

    试试这个:

    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复制到结果中,并减少条目以获得平均值。

        3
  •  1
  •   DjaouadNM    5 年前

    如果id和日期字符串没有逗号( , )在它们中,然后您可以使用这个解决方案,我首先生成一个对象,其中键是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);
        4
  •  0
  •   Max Voisard    5 年前

    首先,我将声明我们将在本例中使用的数组:

    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));