【问题标题】:Filter an array of objects by key and nested value in JavaScript在 JavaScript 中按键和嵌套值过滤对象数组
【发布时间】:2022-01-12 00:38:09
【问题描述】:

我有一组与事件相关的对象。事件按键/值组织,其中键是月初的日期时间,值是数组或在该月内具有特定日期时间的对象。

allEvents = [
    {
        key: "Dec 2021",
        value: [
            { id: 0, date: "Dec 06 2021" },
            { id: 1, date: "Dec 01 2021" },
        ],
    },
    {
        key: "Nov 2021",
        value: [
            { id: 0, date: "Nov 27 2021" },
            { id: 1, date: "Nov 23 2021" },
            { id: 2, date: "Nov 10 2021" },
        ],
    },
    {
        key: "Oct 2021",
        value: [
            { id: 0, date: "Oct 27 2021" },
            { id: 1, date: "Oct 23 2021" },
            { id: 2, date: "Oct 10 2021" },
        ],
    },
];

我需要按给定的日期范围过滤这些事件,例如 2021 年 11 月 15 日 - 2021 年 12 月 4 日

这应该过滤掉十月对象以及在给定日期范围内的任何事件,同时保留父对象。 所以结果是:

filteredEvents = [
    {
        key: "Dec 2021",
        value: [
            { id: 1, date: "Dec 01 2021" },
        ],
    },
    {
        key: "Nov 2021",
        value: [
            { id: 0, date: "Nov 27 2021" },
            { id: 1, date: "Nov 23 2021" },
        ],
    },
];

到目前为止,我已经在月级别完成了如下过滤,但无法弄清楚如何处理日级别。

const dateRange = ["Nov 15 2021", "Dec 04 2021"];
const min = dateRange[0].getTime();
const max = dateRange[1].getTime();

const filteredEvents = allEvents.filter(
  eventGroup => new Date(eventGroup.key).getTime() >= min && new Date(eventGroup.key).getTime() <= max);

理想情况下只想使用 ES6,但可以使用 lodash。

【问题讨论】:

    标签: javascript arrays object


    【解决方案1】:

    一方面,

    const min = dateRange[0].getTime();
    const max = dateRange[1].getTime();
    

    需要:

    const min = new Date(dateRange[0]).getTime();
    const max = new Date(dateRange[1]).getTime();
    

    然后,在初始循环之后,我会做一个映射,以便从value 中删除元素。逻辑将与您已有的过滤器非常相似。

    【讨论】:

      【解决方案2】:

      这看起来有点笨拙,但很简单。首先,map 您的数组并过滤掉任何不适合该范围的value.date。然后简单地过滤掉任何具有零长度值数组的父元素。

      const filteredEvents = (from, to) => allEvents
        .map( g => 
           ({...g, 
             value: g.value.filter(f => 
               new Date(f.date).getTime() >= new Date(from).getTime() && 
               new Date(f.date).getTime() <= new Date(to).getTime())
            }))
        .filter(f => f.value.length>0);
      

      let allEvents = [{
          key: "Dec 2021",
          value: [{
              id: 0,
              date: "Dec 06 2021"
            },
            {
              id: 1,
              date: "Dec 01 2021"
            },
          ],
        },
        {
          key: "Nov 2021",
          value: [{
              id: 0,
              date: "Nov 27 2021"
            },
            {
              id: 1,
              date: "Nov 23 2021"
            },
            {
              id: 2,
              date: "Nov 10 2021"
            },
          ],
        },
        {
          key: "Oct 2021",
          value: [{
              id: 0,
              date: "Oct 27 2021"
            },
            {
              id: 1,
              date: "Oct 23 2021"
            },
            {
              id: 2,
              date: "Oct 10 2021"
            },
          ],
        },
      ];
      
      
      const filteredEvents = (from, to) => allEvents
        .map( g => ({...g, value: g.value.filter(f => new Date(f.date).getTime() >= new Date(from).getTime() && new Date(f.date).getTime() <= new Date(to).getTime())})).filter(f => f.value.length>0);
      
      console.log(filteredEvents("Nov 15 2021", "Dec 04 2021"));

      【讨论】:

      • 这很棒。我太线性地处理这个问题......按月过滤,然后按天过滤。好喊只过滤掉日子,然后删除空的月份。
      【解决方案3】:

      每个事件的值都有一个完整的日期。使用它们排除范围之外的日期,然后排除任何没有值的事件。

      const allEvents = [
          {
              key: "Dec 2021",
              value: [
                  { id: 0, date: "Dec 06 2021" },
                  { id: 1, date: "Dec 01 2021" },
              ],
          },
          {
              key: "Nov 2021",
              value: [
                  { id: 0, date: "Nov 27 2021" },
                  { id: 1, date: "Nov 23 2021" },
                  { id: 2, date: "Nov 10 2021" },
              ],
          },
          {
              key: "Oct 2021",
              value: [
                  { id: 0, date: "Oct 27 2021" },
                  { id: 1, date: "Oct 23 2021" },
                  { id: 2, date: "Oct 10 2021" },
              ],
          },
      ];
      
      const dateRange = ["Nov 15 2021", "Dec 04 2021"];
      const [min, max] = dateRange.map(d => new Date(d).getTime());
      
      const filteredEvents = allEvents.map(({key,value}) => ({
          key,
          value:value.filter(({date:d}) => 
              new Date(d).getTime() >= min && new Date(d).getTime() <= max)
      }))
      .filter(({value:v}) => v.length);
        
      console.log( filteredEvents );

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-10-15
        • 1970-01-01
        • 2021-09-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-09
        • 2022-12-03
        相关资源
        最近更新 更多