如何按指定字段分组过滤JavaScript对象数组并保留最小时间戳分组
你可以用两次哈希表配合单次遍历的方式实现,整体时间复杂度为O(n),比嵌套遍历的效率高很多:
实现思路
- 先按
start_time对所有元素分组,同组内对file字段去重,同一个时间下如果出现重复file只保留第一个即可 - 把所有分组按时间戳升序排序,保证时间更早的分组优先被处理
- 遍历排序后的分组,用哈希表记录已经出现过的
file集合,相同集合的后续分组直接过滤,最终剩下的分组就是目标结果
代码实现
function processArray(arr) { // 按start_time分组,同组内file去重 const timeGroupMap = {} arr.forEach(item => { const time = item.start_time if (!timeGroupMap[time]) { timeGroupMap[time] = { timestamp: new Date(time).getTime(), fileMap: {}, items: [] } } const currentGroup = timeGroupMap[time] if (!currentGroup.fileMap[item.file]) { currentGroup.fileMap[item.file] = true currentGroup.items.push(item) } }) // 分组按时间升序排序 const sortedGroups = Object.values(timeGroupMap).sort((a, b) => a.timestamp - b.timestamp) // 过滤重复file集合的分组 const usedFileSets = new Set() const result = [] sortedGroups.forEach(group => { // 把当前分组的file排序后拼接为唯一标识,避免分组内元素顺序不同导致判定为不同集合 const fileSetKey = Object.keys(group.fileMap).sort().join(',') if (!usedFileSets.has(fileSetKey)) { usedFileSets.add(fileSetKey) result.push(group.items) } }) return result } // 测试用例 const objArray = [ { file: 'file_1', start_time: '2021-08-12 14:00:00', status: 'pending' }, { file: 'file_2', start_time: '2021-08-12 14:00:00', status: 'completed' }, { file: 'file_3', start_time: '2021-08-14 15:00:00', status: 'pending' }, { file: 'file_1', start_time: '2021-08-14 03:00:00', status: 'pending' }, { file: 'file_2', start_time: '2021-08-14 03:00:00', status: 'pending' }, { file: 'file_2', start_time: '2021-11-11 11:11:00', status: 'pending' } ] console.log(processArray(objArray))
说明
全程只有3次线性遍历+1次分组排序,如果原始数组里start_time的数量远小于数组总长度,排序开销可以忽略不计。所有去重判断都是哈希表O(1)的查找复杂度,数据量增长时性能不会出现明显下降。
内容的提问来源于stack exchange,提问作者ahkam
相关产品推荐
相关产品推荐

