Trying to filter an array of objects based on an object returned by user, returning a new array. I've tried everything I could. Can't get what others have posted to work either because I need to check every object value to be either matching or undefined in the user object (undefined means user has no preference, lets say). Here is what I have come up with, three functions. None of these functions work. Even one working solution is great, but if someone has time to explain why the rest don't work that would be a bonus. This should return the Ford Mustang object. Also have to figure out how to specify a range of numbers, for the zeroSixty. I'm a beginner, having issues with syntax.
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);
CodePudding user response:
I've created a jsfiddle you can look at here: https://jsfiddle.net/rlouie/6osq9kgn/1/
With the criteria you specified, this works:
function filterToDefinedAndMatching(car) {
return Object.entries(car).every(([key, value]) => !userCar[key] || userCar[key] == value);
}
const matchingCars = carArray.filter(filterToDefinedAndMatching);
However, you will run into problems once you want to match on drive, since it is an array. Array equality is by reference not value, and it won't match, so you need even more:
function betterFilterToMatchCars(car) {
return Object.entries(car).every(([key, value]) => {
const userCarValue = userCar[key];
if (Array.isArray(userCarValue)) {
return userCarValue.every(item => value.includes(item));
} else {
return !userCarValue || userCarValue == value;
}
});
}
If your car object keeps getting more complex, you really just need a more generic deep equals check, which you can find more about here: Object comparison in JavaScript