如何筛选含指定车身类型的汽车品牌数组并优化代码?
优化汽车品牌筛选逻辑的解决方案
问题背景
我拥有三个数组:
- 汽车品牌数组
const brands = [ { id: 1, name: "Mercedes Benz", bodyType: [1, 3] }, { id: 2, name: "Audi", bodyType: [1, 2] }, { id: 3, name: "BMW", bodyType: [3, 4] }, { id: 4, name: "Mazda", bodyType: [1, 2, 4] } ];
- 车身类型数组
const bodyTypes = [ { id: 1, type: "Sedan"}, { id: 2, type: "Coupe"}, { id: 3, type: "Hatchback"}, { id: 4, type: "SUV"} ];
- 已选中的车身类型ID数组
const pickedTypes = [2, 4] // Coupe & SUV
需求:筛选出bodyType数组中包含任意一个选中类型ID的汽车品牌。
原始实现的问题
我写了一段多层循环的代码,虽然能得到预期结果(输出Audi、Mazda、BMW),但存在以下问题:
- 三层嵌套循环导致冗余计算,效率低下
- 同一个品牌如果匹配多个选中类型,会被重复添加到结果数组中
- 运行时出现
[circular object Object]警告
原始代码如下:
const brands = [ { id: 1, name: "Mercedes Benz", bodyType: [1, 3] }, { id: 2, name: "Audi", bodyType: [1, 2] }, { id: 3, name: "BMW", bodyType: [3, 4] }, { id: 3, name: "Mazda", bodyType: [1, 2, 4] } ]; const bodyTypes = [ { id: 1, type: "Sedan"}, { id: 2, type: "Coupe"}, { id: 3, type: "Hatchback"}, { id: 4, type: "SUV"} ]; const pickedTypes = [2, 4] // coupe & suv let newBrandsByPickedTypes = []; // loop for every type for(let i = 0; i < pickedTypes.length; i++){ // loop for every brand for(let k = 0; k < brands.length; k++){ // loop for every type in brand brands[k].bodyType.forEach((type) => { // if brand has type that in pickedTypes push this brand to newBrandsByPickedTypes if(type === pickedTypes[i]){ newBrandsByPickedTypes.push(brands[k]) } }) } } newBrandsByPickedTypes && console.log(newBrandsByPickedTypes); // output audi, mazda, bmw
优化解决方案
核心思路
- 将
pickedTypes转为Set结构,把元素查找的时间复杂度从O(n)降到O(1),提升判断效率 - 使用
Array.filter结合Array.some实现单层筛选逻辑,避免嵌套循环 - 确保每个品牌只被筛选一次,不会重复出现在结果中
优化后的代码
const brands = [ { id: 1, name: "Mercedes Benz", bodyType: [1, 3] }, { id: 2, name: "Audi", bodyType: [1, 2] }, { id: 3, name: "BMW", bodyType: [3, 4] }, { id: 4, name: "Mazda", bodyType: [1, 2, 4] } ]; const pickedTypes = [2, 4]; // 转换为Set提升查找效率 const pickedTypeSet = new Set(pickedTypes); // 筛选符合条件的品牌 const filteredBrands = brands.filter(brand => { // 判断品牌的bodyType是否有任意一个元素在选中集合中 return brand.bodyType.some(typeId => pickedTypeSet.has(typeId)); }); console.log(filteredBrands); // 输出结果:[{id:2, name:"Audi", ...}, {id:3, name:"BMW", ...}, {id:4, name:"Mazda", ...}]
代码解释
new Set(pickedTypes):把选中的类型ID转为集合,后续查找时无需遍历数组,直接通过has方法快速判断brands.filter(...):遍历所有品牌,只保留符合条件的元素brand.bodyType.some(...):检查当前品牌的车身类型数组中,是否存在至少一个ID在选中集合里,只要有一个匹配就返回true,该品牌会被保留到结果中
这种写法不仅代码更简洁,执行效率更高,还解决了原始代码中重复添加品牌的问题,同时避免了循环嵌套导致的性能浪费。
内容的提问来源于stack exchange,提问作者Ev Gen
相关产品推荐
相关产品推荐

