Reputation: 81
I'm trying to create a filter with javascript with 4 input fields so I'm guessin 16 combinations of possible searches. I can search all 4 at once or 1 input at a time but for some reason when I add other statements I get wierd results. Is there a better way to implement a filter?
var unfilteredFloorplans = floorplanJSON.floorplanData;
filteredFloorplans = [];
for (var i = 0; i < unfilteredFloorplans.length; i++) {
if (unfilteredFloorplans[i].city == req.body.cityName &&
unfilteredFloorplans[i].building == req.body.buildingName &&
unfilteredFloorplans[i].bedrooms == req.body.minBedroom &&
unfilteredFloorplans[i].baths == req.body.maxBathroom) {
console.log(unfilteredFloorplans[i].city);
filteredFloorplans.push(unfilteredFloorplans[i]);
}
}
So now I need to write 15 more if statements? Rather than copy them in I'd like to ask if this is correct and does anyone know how you could implement this with a switch statement?
Edit: And when I say 15 more statements I mean one for if they just pick city, andother if they pick city and bedrooms etc. It just seems inefficient
Upvotes: 0
Views: 2830
Reputation: 2261
Here's a simplified example of what your code may look like (in this example, I hardcoded the values representing the input
choices):
var unfilteredFloorplans = [{
city: 'NY',
building: 'A',
bedrooms: 2,
baths: 1,
}];
var filteredFloorplans = unfilteredFloorplans.filter(
function(el) {
return el.city === 'NY' && el.building === 'A' && el.bedrooms >= 1 && el.baths >= 1;
}
);
console.log(filteredFloorplans);
The anonymous function being called inside the filter
can be replaced with a named function like so:
function filterFloorplans(floorplan) {
return floorplan.city === 'NY' && floorplan.building === 'A' && floorplan.bedrooms >= 1 && floorplan.baths >= 1;
}
var filteredFloorplans = unfilteredFloorplans.filter(filterFloorplans);
You'll likely want to use this route since you can have any combination of the 4 input choices. As such, you'll want the filterFloorplans
function to be "built-up" from other, smaller checks:
function testCity(userInputCity, floorplanCity) {
return userInputCity ? userInputCity === floorplanCity : true;
}
function filterFloorplans(floorplan) {
return testCity('NY', floorplan.city) && floorplan.building === 'A' && floorplan.bedrooms >= 1 && floorplan.baths >= 1;
}
This should be enough to get you started; feel free to comment if you get stuck
Upvotes: 0
Reputation: 25647
A minimal fix would be to combine your "and" with "or", but note how this turns the code into a hard-to-read mess:
var unfilteredFloorplans = floorplanJSON.floorplanData;
filteredFloorplans = [];
for (var i = 0; i < unfilteredFloorplans.length; i++) {
if ((req.body.cityName == '' || unfilteredFloorplans[i].city == req.body.cityName) &&
(req.body.buildingName == '' || unfilteredFloorplans[i].building == req.body.buildingName) &&
(req.body.minBedroom == '' || unfilteredFloorplans[i].bedrooms == req.body.minBedroom) &&
(req.body.maxBathroom == '' || unfilteredFloorplans[i].baths == req.body.maxBathroom)) {
console.log(unfilteredFloorplans[i].city);
filteredFloorplans.push(unfilteredFloorplans[i]);
}
}
(BTW, this looks like a good exercise for combining conjunctions with disjunctions.)
Edit I'd recommend to put the filtering into a separate function, and to introduce an additional helper function. Also, use a more consistent naming and use "===" instead of "==".
function filterByEquality(formValue, dataValue) {
if (formValue === '') return true;
if (formValue === dataValue) return true;
return false;
}
function filterFloorplan(form, data) {
if (!filterByEquality(form.city, data.city)) return false;
if (!filterByEquality(form.building, data.building)) return false;
if (!filterByEquality(form.minBedrooms, data.bedrooms)) return false;
if (!filterByEquality(form.maxBathrooms, data.bathrooms)) return false;
return true;
}
var unfilteredFloorplans = floorplanJSON.floorplanData;
filteredFloorplans = [];
for (var i = 0; i < unfilteredFloorplans.length; i++) {
if (filterFloorplan(req.body, unfilteredFloorplans[i]);
console.log(unfilteredFloorplans[i].city);
filteredFloorplans.push(unfilteredFloorplans[i]);
}
}
You can reduce this code even further by learning about the Array.filter method. And you should fix the bug where for some fields should use ">=" or ">=" instead of "===". But I'll leave those things as an exercise.
Upvotes: 2