【问题标题】:How to filter and map Array in JavaScript如何在 JavaScript 中过滤和映射数组
【发布时间】:2022-01-02 14:52:33
【问题描述】:

原始数组中有几个对象,每个对象都有三个属性(时间戳、名称和年龄)。

如果连续多个时间戳相隔 15 分钟,它们将被分组到同一个对象中。之后,将添加一个名为 end 的新属性,该属性将是该组的最后一个元素的时间戳值加上 15 分钟。

如果一行中没有多个元素之间相差 15 分钟,则 end 属性将时间戳加上 15 分钟作为值。

这是我当前的代码:

const data = [
    {
        timestamp: '2021-11-23T14:15:00+0000',
        name: 'John',
        age: 25,
    },
    {
        timestamp: '2021-11-23T14:30:00+0000',
        name: 'John',
        age: 25,
    },
    {
        timestamp: '2021-11-23T14:45:00+0000',
        name: 'John',
        age: 25,
    },
    {
        timestamp: '2021-11-23T15:45:00+0000',
        name: 'John',
        age: 25,
    },
    {
        timestamp: '2021-11-23T14:15:00+0000',
        name: 'Anne',
        age: 32,
    },
    {
        timestamp: '2021-11-23T14:30:00+0000',
        name: 'Anne',
        age: 32,
    },
    {
        timestamp: '2021-11-23T14:45:00+0000',
        name: 'Anne',
        age: 32,
    },
    {
        timestamp: '2021-11-23T15:45:00+0000',
        name: 'Anne',
        age: 32,
    },
]

const newArray = data.reduce((accumulator, current) => {
    const end = new Date(Date.parse(current.timestamp) + 15 * 60 * 1000)
    if (accumulator.length === 0) {
        accumulator.push({
            ...current,
            end,
        })
    } else {
        const last = accumulator[accumulator.length - 1]
        if (last.name === current.name && last.age === current.age) {
            last.end = end
        } else {
            accumulator.push({
                ...current,
                end,
            })
        }
    }
    return accumulator
}, [])

console.log(newArray)

但是我的代码的最终结果并不是我想要的。我希望我的结果是这样的:

[
    {
        timestamp: '2021-11-23T14:15:00+0000',
        name: 'John',
        age: 25,
        end: '2021-11-23T15:00:00+0000'
    },
    {
        timestamp: '2021-11-23T15:45:00+0000',
        name: 'John',
        age: 25,
        end: '2021-11-23T16:00:00+0000'
    },
    {
        timestamp: '2021-11-23T14:15:00+0000',
        name: 'Anne',
        age: 32,
        end: '2021-11-23T15:00:00+0000'
    },
    {
        timestamp: '2021-11-23T15:45:00+0000',
        name: 'Anne',
        age: 32,
        end: '2021-11-23T16:00:00+0000'
    }
]

【问题讨论】:

  • 为什么输出的对象数量是输入的一半?
  • @ze00ne 我不明白这个问题。我想这样做,这样我处理数据会更简单。
  • 最终结果有4个对象{},而原始数组有8个对象{}...为什么?
  • 只是一个问题,你是在问我为什么要从 8 个对象变为 4 个对象? @zer00ne

标签: javascript arrays javascript-objects


【解决方案1】:

您可以搜索最后一个间隔并更新end(如果找到)。否则添加一个新对象。

const data = [{ timestamp: '2021-11-23T14:15:00+0000', name: 'John', age: 25 }, { timestamp: '2021-11-23T14:30:00+0000', name: 'John', age: 25 }, { timestamp: '2021-11-23T14:45:00+0000', name: 'John', age: 25 }, { timestamp: '2021-11-23T15:45:00+0000', name: 'John', age: 25 }, { timestamp: '2021-11-23T14:15:00+0000', name: 'Anne', age: 32 }, { timestamp: '2021-11-23T14:30:00+0000', name: 'Anne', age: 32 }, { timestamp: '2021-11-23T14:45:00+0000', name: 'Anne', age: 32 }, { timestamp: '2021-11-23T15:45:00+0000', name: 'Anne', age: 32 }]

const newArray = data.reduce((accumulator, current) => {
    const
        end = new Date(Date.parse(current.timestamp) + 15 * 60 * 1000).toISOString(),
        item = accumulator.find(o =>
            o.name === current.name &&
            o.end === new Date(current.timestamp).toISOString()
        );
    
    if (item) item.end = end;
    else accumulator.push({ ...current, end });

    return accumulator;
}, [])

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

【讨论】:

    【解决方案2】:

    您可以像在自己的代码中一样使用Array.reduce() 来获得所需的结果,但我们可以稍作更改以更新累加器数组中的 lastItem

    • 名称相同(lastItem.name === name)
    • 日期在 15 分钟内

    如果不满足这个条件,我们只需添加到累加器数组中。

    const data = [ { timestamp: '2021-11-23T14:15:00+0000', name: 'John', age: 25, }, { timestamp: '2021-11-23T14:30:00+0000', name: 'John', age: 25, }, { timestamp: '2021-11-23T14:45:00+0000', name: 'John', age: 25, }, { timestamp: '2021-11-23T15:45:00+0000', name: 'John', age: 25, }, { timestamp: '2021-11-23T14:15:00+0000', name: 'Anne', age: 32, }, { timestamp: '2021-11-23T14:30:00+0000', name: 'Anne', age: 32, }, { timestamp: '2021-11-23T14:45:00+0000', name: 'Anne', age: 32, }, { timestamp: '2021-11-23T15:45:00+0000', name: 'Anne', age: 32, }, ] 
        
    const result = data.reduce((acc, { timestamp, name, age }) => { 
        let lastItem = acc[acc.length - 1];
        let end = new Date(Date.parse(timestamp) + 15*60*1000);
        
        // If the current row matches just update the end time
        if (lastItem && lastItem.name === name && (Date.parse(lastItem.end) - Date.parse(timestamp) >= 0)) { 
            lastItem.end = end;
        } else {
            acc.push({ timestamp, name, age, end });
        } 
        return acc;
    }, [])
    
    console.log(result)
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    【讨论】:

      猜你喜欢
      • 2020-11-23
      • 1970-01-01
      • 1970-01-01
      • 2022-01-14
      • 2022-01-13
      • 2021-03-15
      • 1970-01-01
      • 2019-09-29
      • 2020-12-03
      相关资源
      最近更新 更多