如何使用Lodash/JavaScript实现多层GroupBy嵌套
React Native SectionList 双层分组(按日期→地点)解决方案
嘿,我来帮你搞定这个SectionList的双层分组需求!你需要把游戏数据先按date做外层分组,每组内再按location做内层分组,最终结构要完全匹配SectionList需要的title+data格式对吧?
完整解决方案代码
假设你已经引入了lodash(你原来的代码里也在用它),直接用下面的代码就能得到你想要的结构:
import _ from 'lodash'; // 你的原始游戏数据 const games = [ { game_id: 1171, date: '2018-11-17', location: 'Plaza' }, { game_id: 1189, date: '2018-11-17', location: 'Field - Kickball' }, { game_id: 1489, date: '2018-11-16', location: 'Field - Kickball' }, { game_id: 1488, date: '2018-11-16', location: 'Field - Soccer' } ]; // 生成符合要求的双层分组数据 const groupedData = _(games) // 第一步:按日期分组,得到以日期为键、对应游戏数组为值的对象 .groupBy('date') // 第二步:遍历每个日期分组,生成外层的section .map((gamesInDate, date) => { // 对当前日期下的游戏,再按地点分组并转换格式 const locationSections = _(gamesInDate) .groupBy('location') // 把每个地点分组转换成 { title: 地点名, data: 对应游戏数组 } .map((gamesInLocation, location) => ({ title: location, data: gamesInLocation })) .value(); // 返回外层的section对象 return { title: date, data: locationSections }; }) .value();
原有代码的问题说明
你原来的代码有两个小疏漏:
- 第二层
map时,你用了({key, value})解构,但_.groupBy返回的对象在map遍历中,第一个参数是分组的值,第二个参数才是分组的键,应该直接用(gamesByLocation, location)来获取地点和对应数据。 - 获取外层
title的方式太绕——遍历日期分组时,直接就能拿到date这个键值,完全不需要去数组里取第一个元素的date属性。
额外优化小技巧
如果需要给分组排序(比如日期从新到旧,或者地点按名称排序),可以在对应的value()之前加上排序逻辑:
- 外层日期倒序:在最外层的
.map(...)之后加.sort((a, b) => new Date(b.title) - new Date(a.title)) - 内层地点按名称排序:在
locationSections的.map(...)之后加.sortBy('title')
运行上面的代码后,groupedData就完全是你期望的格式啦,直接传给SectionList的sections属性就能用了!
内容的提问来源于stack exchange,提问作者Eyal Abadi




