0

Filtering carArray with a certain conditions from user.

When user checked red checkbox, it will filter cars with red paint. When user checked green checkbox, it will filter cars with green paint. When user checked both red and green checkbox, it will show both red and green cars. (and so on with N user conditions)

I am using 2 check boxes for this example. I have more than 5 check boxes in my real implementation.

I started with showRed, showGreen boolean vars to track what users wants and an array of car object.

[ {
       carName: xxx, 
       color: 'red'
  },
  {
       carName: yyy, 
       color: 'green'
  },
   .....
]

filteredCars = carArray.filter((car) => {
    // Problem: I tried to check for showRed and 
    // showGreen before returning but found out that I can 
    // only return once in here
    if (showRed) {
        return car.color === 'red';
    }
    if (showGreen) {
        return car.color === 'green';
    }
});

I am currently facing some problems on filtering with multiple user conditions.

1
  • So, even if showRed is true and car.color is not red, you still want to check if car.color could be green? Commented Apr 27, 2018 at 8:32

7 Answers 7

5

Why not put the wanted colors in an array colors and check against the car color

filteredCars = carArray.filter(({ color }) => colors.includes(color));
Sign up to request clarification or add additional context in comments.

Comments

4

On checkbox change, you should build an array of checked colors. For example, if red and green are checked, produce an array of ['red', 'green']. Then, for your filter function, test to see if the car's color is included in that array:

// colorsToShow = ['red', 'green']
const filteredCars = carArray.filter(({ color }) => colorsToShow.includes(color));

Comments

0

A quick guess: return exits the calling stack. You should continue iterating and populate a temporary array with the found correct entries, then return the array. That is, do a 'greedy' search.

Comments

0

Using Jquery

let selection = [];


$(".checkBox").each(function() { //you can change .checkBox to your checkBox Id.
    if ($( this ).prop("checked")){
        selection.push( $( this ).text() );
    }
})

You can use this snippet.

Then build your filter with this array.

Comments

0

Here is how you can build your filter function using a getter that gets a value from an object (in this case color) and a comparer that will compare that value and return true or false (in this case a function named hasColor that is partially applied with a set of colors):

const arr = [ 
  {
    carName: "xxx", 
    color: 'red'
  },
  {
    carName: "yyy", 
    color: 'green'
  }
]
//function to get an item from an object (in this case color)
//  defaults to empty string if o or o.tags doesn't exist
const getColor = o => (o&&o.color) || ""; 

//function to compare a value, in this case a string with array of strings
//  in this case the haystack is the colors you are looking for and the needle
//  is the color of the current car
const compareSomePrimitive = (hayStack,needle) =>
  hayStack.includes(needle);
//curryable function to filter, takes 2 functions:
//  getter: to get the value to compare from the object passed into it 
//    like getColor to get color from a car
//  comparer: to compare the value 
const filterFn = getter => comparer => object =>
  comparer(getter(object))
//partially applied filterFn getting the color property from a car
const filterColor = filterFn(getColor);

//partially applied filterFn that has getter and comparer, only need to pass the car to finish
const hasColor = whatColors=>
  filterColor(
    currentColor =>
      compareSomePrimitive(whatColors,currentColor)
  );
//use hasColor filter function
console.log(
  "has color red or green",
  arr.filter(hasColor(["red","green"]))
)

//example with showRed, showGreen
const getColors = settings => {
  var colors = ["red","green"];
  if(!settings.showRed){
    colors = colors.filter(color=>color!=="red");
  }
  if(!settings.showGreen){
    colors = colors.filter(color=>color!=="green");
  }
  return colors;
};

console.log(
  "has color red or green with showRed, showGreen",
  arr.filter(hasColor(
    getColors(
      {showRed:true,showGreen:false}
    )
  ))
)

Comments

0

My two cents on this case is that I would group cars by color so I don't need to filter each car one by one whenever checkboxes are changed.

I would get cars of checked colors from a map (where the key is a color and value an array of cars of that color).

In the other hand, I've used ramda to avoid boilerplate as it already implements groupBy.

const cars = [{
    carName: 'xxx',
    color: 'red'
  },
  {
    carName: 'yyy',
    color: 'green'
  }
]

const carMap = R.groupBy(car => car.color, cars)

// A function to get multiple keys of a given map
// (using objects instead of Map). It will get one or 
// more arrays, and that's why I use R.flatten: to get a flat 
// array of cars of different colors
const multiMapGet = (keys, map) => R.flatten(keys.map(key => map[key]))

// The array of colors would be the checked checkbox selected
// colors
const carsOfColors = multiMapGet(['red', 'green'], carMap)

console.log(carsOfColors)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js"></script>

Comments

0
let filteredCars=[];
            let filteredData = carsArray.filter(function(car){
                    if(showRed && car.color === 'red') {
                        filteredCars.push(car);
                    }
                    if(showGreen && car.color === 'green') {
                        filteredCars.push(car);
                    }
                    //any other color or filter that u want to implement can go here
            })

The filteredCars will contain the list of cars that are available after applying all the filters.

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.