Filtering With Multiple Criteria — React

Sean Ottomanelli
5 min readJun 3, 2021

I was recently working on a mock eye-wear retail website with a partner. We wanted the user of the website to be able to filter the collection of available eye-wear based on glasses color, material, manufacturer, lens-tint (sunglasses or corrective lenses) and gender. We intended for the user to be able to check off any number (or none) of the options for each of these categories. Upon ticking or unticking each box the collection of glasses was to update accordingly. As far as intent goes the requirements sound easy enough but when you really drill down into the logistics this is a complicated problem. Observe:

Example filter criteria

If no filter options are selected all glasses are shown regardless of color, material, manufacturer, lens-tint, or gender. As soon as the blue-color is checked all glasses that are blue are shown, regardless of manufacturer, material, lens-tint, or gender. If the Prada-manufacturer is subsequently checked all glasses that are blue AND Prada are shown, regardless of material, lens-tint, or gender. If the metal-material is selected all glasses that are blue AND Prada AND metal are shown regardless of lens-tint or gender… This seems simple enough. However consider this: If the red-color is then also selected all glasses that are blue OR red AND Prada AND metal are shown. If the acetate-material is also then also checked all glasses that are red OR blue AND Prada AND metal OR acetate are shown. Keep in mind that no gender has yet been selected and for this reason glasses designed for all genders are displayed; However if the Men’s gender is selected in addition to showing all glasses that are Men’s AND blue OR red AND Prada AND metal OR acetate, we also want to show all glasses that are Unisex AND blue OR red AND Prada AND metal OR acetate, because no matter the gender selected we always display the unisex glasses.

Now consider the fact that there may be 10 colors, 5 materials, 20 manufacturers and so on and so forth and the user needs to be able to select any number (or none) of these options. How do we code a filter to show only glasses that are blue OR red OR gold OR silver OR purple AND Prada OR Warby Parker OR Tom Ford AND acetate OR wood AND Mens OR Unisex… and what if in the future we want to filter by size, or lens-colors, or styles? My head hurts. How can we neatly filter without letting our code turn into a mess of AND’s and OR’s?

An innocent coder trying to filter with multiple criteria.

There are likely many ways to neatly and concisely filter a data set with multiple criteria, however I am going to explain one that my partner and I used for our mock retail website:

The first lines to consider when breaking down this code are lines 214, and 240. When looked at together they are saying:

214: “iterate over every pair of glasses in the collection of all glasses and…”

240: “…if, for any pair of glasses that we iterate across, typeSatisified is true, AND, colorSatisified is true, AND, brandSatisified is true, AND, genderSatisifed is true, AND, materialSatisified is true return the pair of glasses, otherwise return nil.

Iteration Illustration

All glasses that are returned are stored in the filteredGlasses array declared at the beginning of line 214, and the the glasses contained within the array are rendered on the web app. Since the array changes with the state which is determined by the filter checkboxes, the glasses render and re-render in real time as the user changes their filter parameters.

So whats the rest of the code from lines 215–238? Here we declare typeSatisfied, colorSatisfied, brandSatisfied, genderSatisfied, and materialSatisfied, and then determine for each pair of glasses whether each of these variables should be true or false. Before diving into how this works, a little about how the filter criteria are stored in state and how the glasses’ qualities are stored on the back end.

Lets look at the color criteria specifically:

When a user checks a box for color, a string equal to that color is saved in a slice of state called “showColor”… as in we’re going to show these colors. If two colors are checked, say for instance the blue checkbox and the red check box, they are both added into the showColor state so that this.state.showColor would return [“blue”, “red”]. Meanwhile on the backend each pair of glasses has a color attribute equal to a single string corresponding to a single color such that glassesObj.color might return “red”.

Now for the colorSatisfied code:

Per line 219, colorSatisfied starts off as false. Line 220 is saying that if the array contained in the showColor state has any elements in it we need to run the line of code on 221. The line of code on 221 uses the .some() method to iterate over all of the colors held in state (i.e the colors we want to display in our website). If .some() finds that any of the colors in state match the color of the glasses currently being iterated over it returns true thus setting colorSatisifed equal to true. If none of the colors in state match the color of the glasses in this iteration .some() returns false thus setting colorSatisfied equal to false. Line 222 says that if on the other hand the showColor state is empty (meaning no color has been selected), colorSatisfied is automatically set to true and all glasses satisfy the color criterion regardless of their color.

The logic described above is more or less repeated for all other filter criterion including material, manufacturer and lense-tint. Gender is slightly different as in addition to being able to filter in and out Men’s and Women’s glasses there are also Unisex glasses which will be displayed despite the gender(s) selected. This condition is handled fairly explicitly on lines 229 and 230.

This filter method is tricky to understand because it iterates across all glasses and then within the glasses iterations it iterates across all of the colors, materials, manufacturers, lens-tints, and genders in series. This multi-criteria filtering conundrum is a problem that will occur during development of any web app which requires multiple layers of filtration. The solution described above is likely one of many but it did exactly what it needed to. There are surely other good solutions to this problem. If you’re aware of any please drop a comment in the comment section with an explanation or a link.

--

--