【问题标题】:How to combine like objects within array of objects and insert new object?如何在对象数组中组合类似的对象并插入新对象?
【发布时间】:2021-04-20 23:35:19
【问题描述】:

我有一个播客应用的对象数组,如下所示:

[{ id: "uuid-1"
   timeInSeconds: 1000
   dateListened: "2021-01-01T15:57:17.000Z" }, // <---same day
{  id: "uuid-2"
   timeInSeconds: 4900
   dateListened: "2021-01-01T16:57:17.000Z" }, // <---same day 
{  id: "uuid-3"
   timeInSeconds: 3200
   dateListened: "2021-09-01T16:57:17.000Z" }, 
{  id: "uuid-4"
   timeInSeconds: 6000
   dateListened: "2021-10-01T16:57:17.000Z" } ]

如果dateListened 在同一天,我想创建一个结合活动时间的函数。我希望它看起来像这样:

[{ id: "uuid-new" 
   timeInSeconds: 5900 // <---- combined seconds listened on Jan 1
   dateListened: "2021-01-01T15:57:17.000Z" },
{  id: "uuid-3"
   timeInSeconds: 3200
   dateListened: "2021-09-01T16:57:17.000Z" }, 
{  id: "uuid-4"
   timeInSeconds: 6000
   dateListened: "2021-10-01T16:57:17.000Z" } ]

我最接近的尝试是使用带有嵌套 .some() 的 .map() 但我仍然远远不够,甚至不值得发布我的尝试。有没有人对下一步尝试什么方向有任何提示或想法?谢谢!

【问题讨论】:

  • 那么您需要多少帮助?你只需要像isSameDay(date1, date2)这样的函数吗?
  • 你的 json 不好
  • 有很多dupes 可供选择。请注意,map 在这里不起作用,因为它总是返回与输入相同数量的元素。要更改输出数量,您通常会使用reduce

标签: javascript arrays ecmascript-6


【解决方案1】:

您可以减少项目并将它们映射到日期键,检索值,然后将它们映射到单个对象。

您可以键入以下内容:

let date = new Date(info.dateListened).toLocaleDateString('en-US')

const data = [
  { id: "uuid-1",
    timeInSeconds: 1000,
    dateListened: "2021-01-01T15:57:17.000Z" }, // <---same day
  { id: "uuid-2",
    timeInSeconds: 4900,
    dateListened: "2021-01-01T16:57:17.000Z" }, // <---same day 
  { id: "uuid-3",
    timeInSeconds: 3200,
    dateListened: "2021-09-01T16:57:17.000Z" }, 
  { id: "uuid-4",
    timeInSeconds: 6000,
    dateListened: "2021-10-01T16:57:17.000Z" }
 ];

const result = Object
  .values(data.reduce((acc, info) =>
    (date =>
      ({ ...acc, [date]: [...(acc[date] || []), info ] }))
    (new Date(info.dateListened).toLocaleDateString('en-US')), {}))
  .map(value => value.length === 1 ? value : {
    id: 'uuid-new',
    timeInSeconds: value.reduce((sum, { timeInSeconds }) => sum + timeInSeconds, 0),
    dateListened: value[0].dateListened
  });

console.log(result);
.as-console-wrapper { top: 0; max-height: 100% !important; }

【讨论】:

    【解决方案2】:

    您可以使用reduce 获得结果,并且仅当yearmonthdate 完全相同/相等时才添加timeInSeconds

    const arr = [
      {
        id: "uuid-1",
        timeInSeconds: 1000,
        dateListened: "2021-01-01T15:57:17.000Z",
      },
      {
        id: "uuid-2",
        timeInSeconds: 4900,
        dateListened: "2021-01-01T16:57:17.000Z",
      },
      {
        id: "uuid-3",
        timeInSeconds: 3200,
        dateListened: "2021-09-01T16:57:17.000Z",
      },
      {
        id: "uuid-4",
        timeInSeconds: 6000,
        dateListened: "2021-10-01T16:57:17.000Z",
      },
    ];
    
    const result = arr.reduce((acc, curr) => {
      const { id, timeInSeconds, dateListened } = curr;
      const searchSameDateElement = acc.find((o) => {
        const first = new Date(o.dateListened);
        const second = new Date(dateListened);
        const isYearSame = first.getFullYear() === second.getFullYear();
        const isMonthSame = first.getMonth() === second.getMonth();
        const isDateSame = first.getDate() === second.getDate();
        return isYearSame && isMonthSame && isDateSame;
      });
      if (!searchSameDateElement) {
        acc.push(curr);
      } else {
        searchSameDateElement.timeInSeconds += timeInSeconds;
      }
      return acc;
    }, []);
    
    console.log(result);

    【讨论】:

      猜你喜欢
      • 2016-04-23
      • 2019-03-16
      • 1970-01-01
      • 1970-01-01
      • 2020-01-28
      • 1970-01-01
      • 2022-07-22
      • 1970-01-01
      相关资源
      最近更新 更多