简体   繁体   中英

How to filter and map Array in JavaScript

The original array has several objects within it, each of these objects has three properties (timestamp, name and age).

If multiple timestamps in a row are 15 minutes apart, they will be grouped into the same object. Afterwards, a new property called end will be added, which will be the timestamp value of the last element of this group plus 15 minutes.

If there are not several elements in a row with a difference of 15 minutes between them, the end property will have the timestamp plus 15 minutes as a value.

This is my current code:

 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)

However the end result of my code is not exactly what I want. I would like my result to be like this:

[
    {
        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'
    }
]

You could search for the last interval and update end if found. Otherwise add a new object.

 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; }

You can use Array.reduce() to get the required result as in your own code, but we can make a slight change to update the lastItem in the accumulator array if

  • The names are the same (lastItem.name === name)
  • The dates are within 15 minutes

If this condition isn't met we simply add to the accumulator array.

 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; }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM