JavaScript如何不硬编码按条件分组筛选对象数组数据
问题描述
需要从混合对象数组中按国家维度拆分数据,要求不能硬编码国家名称,待处理的原始数据集结构如下:
const data = [ {country: {cntryShortName:"USA"}}, {country: {cntryShortName:"USA"}}, {country: {cntryShortName:"CAN"}}, {country: {cntryShortName:"USA"}}, {country: {cntryShortName:"CAN"}}, {country: {cntryShortName:"CAN"}}, {country: {cntryShortName:"USA"}}, {country: {cntryShortName:"USA"}} ]
期望输出为按国家短名归类的分组结构,形式如下:
USA: ..... ..... CAN: ..... .....
之前编写的代码仅能过滤出存在country字段的数组项,无法实现按国家名称自动分组:
const allData = data.filter(item => item.country)
实现方案
使用Array.reduce实现通用自动分组逻辑,无需提前硬编码任何国家名称,遍历过程中会自动识别数据中出现的所有国家编码并创建对应分组,同时自动过滤无效数据项:
const groupedData = data.reduce((result, currentItem) => { // 过滤无country字段、无有效国家短名的无效项 if (!currentItem.country?.cntryShortName) return result const countryCode = currentItem.country.cntryShortName // 首次遇到该国家编码时初始化空数组 if (!result[countryCode]) result[countryCode] = [] // 当前数据推入对应国家分组 result[countryCode].push(currentItem) return result }, {})
方案特性
- 无硬编码:后续新增任意国家(如CHN、GBR等)的数据,无需修改代码即可自动生成对应分组
- 自带数据清洗:自动跳过不符合结构的无效项
- 可复用:修改分组键的取值逻辑,即可快速复用到其他任意字段的分组场景
- 兼容性好:如果运行环境不支持可选链操作符
?.,可将过滤判断替换为if (!currentItem.country || !currentItem.country.cntryShortName) return result即可适配老环境
输出分组内容示例
如果需要按期望格式打印所有分组内容,直接遍历分组结果即可:
Object.entries(groupedData).forEach(([code, itemList]) => { console.log(`${code}:`) itemList.forEach(item => console.log(item)) console.log('\n') })
内容的提问来源于stack exchange,提问作者Prakash Patil
相关产品推荐
相关产品推荐

