Reputation: 165
I'm trying to filter my results using an object with values that are either true
or false
. However, these filters are not mutually exclusive, meaning more than one can be true.
The code shown only allows one filter to work, I assume I need to figure out a way to make showData
dynamic but I'm not too sure how.
const filters = {
letter: {
A: false,
B: false,
C: false,
D: false,
E: false
},
number: {
1: false,
2: false,
3: false,
4: false
},
//...
};
const data = [
{
letter: "A",
number: "1",
},
{
letter: "B",
number: "1",
},
{
letter: "B",
number: "2",
},
//...
],
const results = data.map((result, index) => {
let showData = true;
if (filters.letter.A) showData = result.letter === "A";
if (filters.letter.B) showData = result.letter === "B";
//...
return (showData && result)
})}
An example of expected output is if both filters.letter.A
and filters.letter.B
were true
, then results
would return an array of objects matching these two filters.
Upvotes: 1
Views: 325
Reputation: 419
You probably need that any condition should set showDara, but not clear it.
Simple solution:
//...
if (letter.A) showData = showData || data.letter ===‘A’;
if (letter.B) showData = showData || data.letter ===‘B’;
//...
Advanced:
If I correct in guessing your data, you may simplify the code.
This code will work in case data.letter and data.number is reasonable sanitized values that not interfere with build in or inherited properties:
//...
if(letter[data.letter] === true) showData = true;
if(number[data.number] === true) showData = true;
//...
More advanced:
This code looks more correct, but bit more complex: (Using hasOwnProperty method to check that property defined in object itself and not inherited from parent object):
//...
if(letter.hasOwnProperty(data.letter) && letter[data.letter] === true) showData = true;
if(number.hasOwnProperty(data.number) && number[data.number] === true) showData = true;
//...
Upvotes: 0
Reputation: 371049
Construct an array of the truthy keys in filters.letter
in advance, and then you can set showCard
based on whether the .letter
of the current card being iterated over is included in that array:
const trueLetterKeys = Object.entries(filters.letter)
.filter(([, val]) => val)
.map(([key]) => key);
// ...
{data.map(({ letter }, index) => {
const showCard = trueLetterKeys.includes(letter);
// ...
Doesn't matter when there aren't many items, but to reduce complexity you could use a Set
of truthy keys instead of an array, since a Set
's .has
is quicker than an array's .includes
:
const trueLetterKeys = new Set(
Object.entries(filters.letter)
.filter(([, val]) => val)
.map(([key]) => key)
);
// ...
{data.map(({ letter }, index) => {
const showCard = trueLetterKeys.has(letter);
// ...
Upvotes: 2