0

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

10
  • 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 Commented Mar 6, 2018 at 23:47
  • This looks suspiciously like a homework assignment. Also, why do you use "==" instead of the typesafe "==="? Why do you filter always by equality? (i.e. "bedrooms == minBedroom" instead of "bedrooms >= minBedroom"). Why are the fields named inconsistently? (e.g. bedroom_s_ versus minBedroom (without "s")) Commented Mar 6, 2018 at 23:50
  • Totally unclear what you're trying to do. If you read again and again your own question - you'll understand. Commented Mar 6, 2018 at 23:51
  • It's not homework and if it was I'd be creative enough so you wouldn't know. As for why I use == instead of === it's not going to make a difference here Commented Mar 6, 2018 at 23:51
  • 1
    @baryjones23saturn Can you clarify what your goal is in the question? Also, you may want to look into JavaScript's filter and forEach methods Commented Mar 6, 2018 at 23:56

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

7 Comments

@vog I believe he posted that before you expanded your answer; nonetheless, I kinda agree with his sentiment. If I ever got a Pull Request with the code you gave (correct though it may be), I'd make sure to introduce the submitter to array filters.
Hey this is very helpful I think you guys answered my question in directly. Thank you for the help.
@General_Twyckenham Sure, but that was IMHO the smallest issue with the code.
@vog Hmm, I'm not sure I'd agree with your assessment - you basically just encapsulated the multiple if's into their own function, which will need to be repeated anyway.
@General_Twyckenham thats what I was asking how should it be what is the best practice, you don't have to write code but how should I have done it?
|
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.