You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Observable中使用map()迭代时返回多个值的解决方案

问题描述

我有以下源自Firebase的数据:

const agendaDates = ['2022-12-10', '2022-12-11', '2022-12-12', '2022-12-13']

const events = [
  {
    id: '001',
    fromDate: '2022-12-10',
    toDate: '2022-12-11',
  },
  {
    id: '002',
    fromDate: '2022-12-12',
    toDate: '2022-12-13',
  },
  {
    id: '003',
    fromDate: '2022-12-12',
    toDate: '2022-12-12',
  },  
]

希望将这些数据组合成如下指定结果:

const result = [
  {
    "agendaDate": "2022-12-10",
    "id": "001",
    "fromDate": "2022-12-10",
    "toDate": "2022-12-11"
  },
  {
    "agendaDate": "2022-12-11",
    "id": "001",
    "fromDate": "2022-12-10",
    "toDate": "2022-12-11"
  },
  {
    "agendaDate": "2022-12-12",
    "id": "002",
    "fromDate": "2022-12-12",
    "toDate": "2022-12-13"
  },
  {
    "agendaDate": "2022-12-12",
    "id": "003",
    "fromDate": "2022-12-12",
    "toDate": "2022-12-12"
  },      
  {
    "agendaDate": "2022-12-13",
    "id": "002",
    "fromDate": "2022-12-12",
    "toDate": "2022-12-13"
  }
]

当前使用array.map()遍历agendaDates的createAgenda方法,在同一天存在多个事件时无法正常工作:

private createAgenda(): Observable<any[]> {
  return combineLatest([of(agendaDates), of(events)],
    (agendaDates, events) => (
      agendaDates.map(
        agDate => (
           {
            agendaDate: agDate, ...events.find(
              event => {
                return (this.isDateInRange(agDate, event.fromDate, event.toDate)) ? event : false
              }
            )
          }
        )
      ).filter(ev => ev.id != null)
    )
  )
}

日期范围检查辅助方法:

private isDateInRange(date: string, startDate: string, endDate: string): boolean {
  if (date !== undefined && startDate !== undefined && endDate !== undefined) {
    return (new Date(date) >= new Date(startDate) && new Date(date) <= new Date(endDate))
  } else return false
}

请问实现该需求的最优方案是什么?


最优解决方案

问题根源

当前代码使用events.find(),该方法只会返回第一个匹配的事件,导致同一天有多个事件时,后续事件被忽略,无法生成对应的条目。

改进思路

遍历每个日程日期,对每个日期找到所有匹配的事件,为每个匹配事件生成一条包含agendaDate的记录,最后将所有记录合并为一个数组。

代码实现

private createAgenda(): Observable<any[]> {
  return combineLatest([of(agendaDates), of(events)],
    (dates, events) => {
      // 遍历每个日程日期,扁平化处理匹配的事件条目
      return dates.flatMap(date => {
        // 筛选当前日期下所有符合范围的事件
        const matchedEvents = events.filter(event => this.isDateInRange(date, event.fromDate, event.toDate));
        // 为每个匹配事件添加agendaDate字段
        return matchedEvents.map(event => ({
          agendaDate: date,
          ...event
        }));
      });
    }
  );
}

关键优化点

  • 使用flatMap替代map:将每个日期对应的多个事件数组扁平化为单个条目数组,避免嵌套结构。
  • 使用filter替代find:返回所有匹配的事件,确保同一天的多个事件都能生成对应的记录。
  • 保留原isDateInRange方法:日期范围校验逻辑正确,可直接复用。

验证结果

运行上述代码后,将生成与预期完全一致的结果数组,包含所有日期对应的事件条目,包括同一天的多个事件。

内容的提问来源于stack exchange,提问作者RePLaY

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 20:10:25