【问题标题】:Sum multiple objects to an array based on property [duplicate]根据属性将多个对象求和到数组中[重复]
【发布时间】:2019-11-16 19:46:00
【问题描述】:

我想将所有具有相同日期值的对象合并到一个对象数组中。

我已经尝试过使用地图功能了。

我必须关注对象的类型

[
{a:1, b:2, date:'2019-01-05'}, {a:12, b:22, date:'2019-01-05'}, {a:13, b:23, date:'2019-01-05'},
{a:11, b:2, date:'2019-01-06'}, {a:1, b:22, date:'2019-01-06'}, {a:1, b:23, date:'2019-01-07'}
]

现在我想要一个这样的对象,我总结所有具有相同日期的对象:

[{date:'2019-01-05', data:[{a:1,b:2},....and so on]}]

所以目前我想出了这个解决方案:

  items = [...]
  moddedItems = [];
   this.items.map((data)=>{
      let tempArray = this.items.filter((obj) => {
        return obj.date === data.date;
      });
      this.moddedItems = [...this.moddedItems, {date:data.date, data:[...tempArray]}];
      console.log(this.moddedItems)
    });

【问题讨论】:

    标签: javascript typescript


    【解决方案1】:

    您可以使用Map 以日期为键,对于每个对象,您最初都将存储一个具有空data 属性的对象,然后您将通过迭代原始数据来填充data 属性:

    const data = [
        {a:1, b:2, date:'2019-01-05'}, {a:12, b:22, date:'2019-01-05'}, {a:13, b:23, date:'2019-01-05'},
        {a:11, b:2, date:'2019-01-06'}, {a:1, b:22, date:'2019-01-06'}, {a:1, b:23, date:'2019-01-07'}
    ];
    
    const map = new Map(data.map(({date}) => [date, { date, data: [] }]));
    data.forEach(({date, ...o}) => map.get(date).data.push(o));
    const result = [...map.values()];
    
    console.log(result);

    【讨论】:

    • 嘿,我喜欢你的回答。我找到了针对我当前数据的解决方案并将其发布在上面。你能好心告诉我为什么你的可能更好,或者我的缺陷在哪里?
    • 啊它被标记为重复我将在另一个线程中深入挖掘。无论如何谢谢:)
    • 您自己的解决方案在循环中有一个循环,这会降低效率。最好有某种散列(按日期),例如像我在这里所做的那样使用Map。另一个答案也有同样的缺陷:find 方法可能会迭代大部分收集的数组,这使其成为 O(n²) 解决方案,而我建议的解决方案是 O (n) 时间复杂度。
    • 所以我调整了每个对象中的日期,分组对我来说是最重要的,谢谢你的回答:)
    • 请注意您的意思,因为 date 已经在对象中,但也许您希望日期也在 data 数组中的对象中(这不是您的问题尽管)。无论如何,任何适合你的东西;)
    【解决方案2】:

    Array.map(...) 不是在这里使用的合适函数,因为您想要一个元素少于原始数组的结果数组,您可以使用Array.reduce(...) 生成所需的结果,这是一个示例:

    const arr = [
    {a:1, b:2, date:'2019-01-05'}, {a:12, b:22, date:'2019-01-05'}, {a:13, b:23, date:'2019-01-05'},
    {a:11, b:2, date:'2019-01-06'}, {a:1, b:22, date:'2019-01-06'}, {a:1, b:23, date:'2019-01-07'}
    ];
    
    const result = arr.reduce((a, c) => {
      const o = {
        a: c.a,
        b: c.b
      }
      const found = a.find(({ date }) => date === c.date);
      if (found) {
        found.data.push(o)
      } else {
        a.push({
          date: c.date,
          data: [o]
        })
      }
      return a;
    }, []);
    
    console.log(result)

    【讨论】:

    • 嘿,我喜欢你的回答。我找到了针对我当前数据的解决方案并将其发布在上面。你能好心告诉我为什么你的可能更好,或者我的缺陷在哪里?
    • 啊它被标记为重复我将在另一个线程中深入挖掘。无论如何谢谢:)
    • @HenrySachs 不一定不正确只是令人困惑,您通常将.map 用于其他内容,您可以将.map 替换为.forEach,因为您只是在迭代数组(不要使用来自.map 的返回值)。此外,在您的示例中,data 数组中的对象还包含 date 属性。
    猜你喜欢
    • 2021-04-21
    • 1970-01-01
    • 2016-05-15
    • 2019-09-09
    • 2018-05-25
    • 1970-01-01
    • 2016-11-08
    • 2018-03-11
    • 1970-01-01
    相关资源
    最近更新 更多