如何基于用户筛选条件过滤JavaScript对象数组?
问题:根据筛选条件过滤汽车数组并实现数值范围筛选
我需要根据用户提供的筛选对象过滤汽车数组,返回符合条件的新数组。筛选规则是:用户对象中属性值为undefined表示无偏好,只需要匹配那些有指定值的属性。另外还需要实现zeroSixty属性的数值范围筛选(比如用户如果指定{zeroSixty: {min: 3, max: 4}},就匹配加速时间在3-4秒之间的车)。
我写了三个函数都没法正常工作,希望能得到一个可行的方案,最好能解释下我写的函数为什么失败。目标是返回Ford Mustang Mach E这个对象。我是新手,可能存在语法问题。
const carArray = [ { brand: 'Mazda', model: '3', trim: 'base', year: 2022, drive: ['FWD', 'AWD'], LKA: true, laneCenter: false, handsFree: false, style: 'sedan', zeroSixty: 7.5 }, { brand: 'Ford', model: 'Mustang Mach E', trim: 'base', year: 2022, drive: ['FWD', 'AWD'], LKA: true, laneCenter: true, handsFree: true, style: 'SUV', zeroSixty: 3.7 }, { brand: 'KIA', model: 'Forte', trim: 'GT', year: 2022, drive: ['FWD'], LKA: true, laneCenter: true, handsFree: false, style: 'sedan', zeroSixty: 6.4 }, ] const userCar = { brand: undefined, model: undefined, trim: undefined, year: 2022, drive: undefined, LKA: true, laneCenter: true, handsFree: undefined, style: 'SUV', zeroSixty: undefined }; const result = carArray.filter(x => userCar.some(y => (x.Object.values(carArray) === y.Object.values(userCar)) || (y.Object.values(userCar) === undefined))); console.log(result); const condensedCarFilter = (userCar, carArray) => { return carArray.filter(obj => { return obj.values.every(feature => { return ((userCar.values.includes(feature) === true) || (userCar.values.includes(feature) === undefined)); }) }) }; let contensedTest = condensedCarFilter(userCar, carArray); console.log(condensedTest); const findCar = (userCar, carArray) => { filteredArray = []; for (x =0; x < carArray.length; x++) { if ((Object.values(carArray[x]) === Object.values(userCar)) || (Object.values(userCar) === undefined)) { filteredArray.push(carArray[x]) console.log(Object.values(carArray[x])); } } console.log(filteredArray); }; findCar(userCar, carArray);
可行方案
下面的代码实现了需求中的筛选逻辑:跳过undefined的属性、普通属性精确匹配、数组属性(如drive)的交集匹配,以及zeroSixty的数值范围筛选。
const carArray = [ // 原数组内容不变 { brand: 'Mazda', model: '3', trim: 'base', year: 2022, drive: ['FWD', 'AWD'], LKA: true, laneCenter: false, handsFree: false, style: 'sedan', zeroSixty: 7.5 }, { brand: 'Ford', model: 'Mustang Mach E', trim: 'base', year: 2022, drive: ['FWD', 'AWD'], LKA: true, laneCenter: true, handsFree: true, style: 'SUV', zeroSixty: 3.7 }, { brand: 'KIA', model: 'Forte', trim: 'GT', year: 2022, drive: ['FWD'], LKA: true, laneCenter: true, handsFree: false, style: 'sedan', zeroSixty: 6.4 } ]; // 示例:如果要筛选zeroSixty范围,可改为 {zeroSixty: {min: 3, max: 4}} const userCar = { brand: undefined, model: undefined, trim: undefined, year: 2022, drive: undefined, LKA: true, laneCenter: true, handsFree: undefined, style: 'SUV', zeroSixty: undefined }; const filterCars = (userFilters, cars) => { return cars.filter(car => { // 遍历用户的所有筛选属性,必须全部符合条件才保留 return Object.entries(userFilters).every(([key, value]) => { // 用户无偏好,直接通过 if (value === undefined) return true; // 处理zeroSixty的范围筛选 if (key === 'zeroSixty' && typeof value === 'object') { const { min, max } = value; if (min !== undefined && max !== undefined) { return car[key] >= min && car[key] <= max; } else if (min !== undefined) { return car[key] >= min; } else if (max !== undefined) { return car[key] <= max; } return true; } // 处理数组类型的属性(如drive):只要有交集就算匹配 if (Array.isArray(value)) { return value.some(item => car[key].includes(item)); } // 普通属性精确匹配 return car[key] === value; }); }); }; // 测试 const filteredCars = filterCars(userCar, carArray); console.log(filteredCars); // 输出Ford Mustang Mach E对象
原函数失败原因解析
第一个函数(result变量的filter)
const result = carArray.filter(x => userCar.some(y => (x.Object.values(carArray) === y.Object.values(userCar)) || (y.Object.values(userCar) === undefined)));
userCar是对象,不是数组,不能调用数组方法some()- 语法错误:
x.Object.values()应该是Object.values(x),方法调用顺序颠倒 - 数组是引用类型,用
===直接比较Object.values()返回的数组永远不会相等 - 逻辑错误:没有区分
undefined无偏好的规则,直接粗暴比较整个对象的所有值
第二个函数(condensedCarFilter)
const condensedCarFilter = (userCar, carArray) => { return carArray.filter(obj => { return obj.values.every(feature => { return ((userCar.values.includes(feature) === true) || (userCar.values.includes(feature) === undefined)); }) }) };
- 对象没有
values方法,正确写法是Object.values(obj)和Object.values(userCar) - 逻辑错误:需求是匹配指定属性的对应值,而不是判断汽车的属性值是否存在于用户的筛选值中
第三个函数(findCar)
const findCar = (userCar, carArray) => { filteredArray = []; for (x =0; x < carArray.length; x++) { if ((Object.values(carArray[x]) === Object.values(userCar)) || (Object.values(userCar) === undefined)) { filteredArray.push(carArray[x]) console.log(Object.values(carArray[x])); } } console.log(filteredArray); };
- 未声明
filteredArray和x,会变成全局变量,违反语法规范 - 同样用
===比较数组,永远不会相等 - 逻辑错误:
Object.values(userCar)永远返回数组,不可能是undefined,第二个判断条件永远不成立 - 没有处理
undefined表示无偏好的规则,直接比较整个对象的所有值,不符合需求
内容的提问来源于stack exchange,提问作者TheKleyn
相关产品推荐
相关产品推荐

