如何在复杂嵌套对象数组中按指定值筛选数据?
多层嵌套对象数组按特定值筛选问题解析
需求说明
需要在多层嵌套的对象数组中,筛选出所有嵌套结构包含指定值(如"bmw")的顶层对象,并且仅保留该顶层对象中包含目标值的assets子项。
原始数据的关键问题
你定义的原始数组中,每个顶层对象重复定义了assets属性,这会导致后定义的assets覆盖前一个,比如id:"1"的对象,第一个包含bmw的assets会被第二个包含ford的assets覆盖,这是导致你后续结果不符合预期的首要原因。正确的原始数据应该将多个assets合并为一个数组:
const arr = [ { id:"1", name:"name1", assets: [ { cars: { brand : [ { model: "bmw" }, { model: "dodge" } ] } }, { cars: { brand : [ { model: "ford" }, { model: "ferrari" } ] } } ] }, { id:"2", name:"name2", assets: [ { cars: { brand : [ { model: "audi" }, { model: "maseratti" } ] } }, { cars: { brand : [ { model: "mercedes" }, { model: "bmw" } ] } } ] } ]
两次尝试的错误分析
尝试1的问题
arr.filter的回调函数没有返回布尔值,完全没起到筛选顶层对象的作用,最后输出的是被覆盖后的原数组- 用
filtered.push(m)收集的是单个model对象,不是需求中的顶层对象 - 没有对
assets数组进行过滤,无法保留包含目标值的assets项
尝试2的问题
arr.filter的回调函数没有返回任何判断结果(缺少return),导致筛选结果为空数组- 内部的
filter和map操作没有生成用于判断顶层对象是否符合条件的布尔值,也没有处理assets的过滤逻辑
正确解决方案
实现逻辑分为两步:
- 筛选顶层对象:判断当前顶层对象的
assets中是否存在包含目标model的项 - 过滤顶层对象的
assets:仅保留包含目标model的assets子项
完整代码如下:
const arr = [ { id:"1", name:"name1", assets: [ { cars: { brand : [ { model: "bmw" }, { model: "dodge" } ] } }, { cars: { brand : [ { model: "ford" }, { model: "ferrari" } ] } } ] }, { id:"2", name:"name2", assets: [ { cars: { brand : [ { model: "audi" }, { model: "maseratti" } ] } }, { cars: { brand : [ { model: "mercedes" }, { model: "bmw" } ] } } ] } ]; const search = "bmw"; const lowerSearch = search.toLowerCase(); // 筛选并处理顶层对象 const result = arr.map(item => { // 过滤当前对象的assets,仅保留包含目标model的项 const filteredAssets = item.assets.filter(asset => { return asset.cars.brand.some(brand => brand.model.toLowerCase().includes(lowerSearch) ); }); // 如果有符合条件的assets,返回包含过滤后assets的新对象 if (filteredAssets.length > 0) { return { ...item, assets: filteredAssets }; } // 否则返回undefined,后续过滤掉 }).filter(Boolean); // 过滤掉undefined的项 console.log(result);
输出结果
[ { "id": "1", "name": "name1", "assets": [ { "cars": { "brand": [ { "model": "bmw" }, { "model": "dodge" } ] } } ] }, { "id": "2", "name": "name2", "assets": [ { "cars": { "brand": [ { "model": "mercedes" }, { "model": "bmw" } ] } } ] } ]
内容的提问来源于stack exchange,提问作者Ömer Faruk
相关产品推荐
相关产品推荐

