Home > Mobile >  Looping thru nested array, and also being able to search/filter it
Looping thru nested array, and also being able to search/filter it

Time:03-24

today I am coming here to ask for some help on a problem that I've ran into.

So I'm making a dashboard, where it loops thru criminal charges.

So i have it set up in a database with structure of the table looking like this

category charges

So it holds the category, and also the specific charges that belong to that category.

So what I am trying to do is, loop thru the categories, and inside of the category loop also loop thru the charges for that category.

I know I can do this by just mapping thru each category, and then mapping charges inside of the first map. But then we run into a problem. And that problem is that how do I filter that? For example I want to filter by "title" key in charges for each category, so if I search it will filter out and show only the charges that match in any category.

This is the structure of my data: (that's whats inside of the chargesData state)

0: {category: "Infractions", charges: Array(30), color: "#417011", id: 1}
1: {category: "Misdemeanors", charges: Array(60), color: "#7e5800", id: 2}
2: {category: "Felonies", charges: Array(99), color: "#7e2100", id: 3}

Charges structure:

0: {fine: "500", months: "0", points: "0", title: "Failure to stop at Red Light"}
1: {fine: "500", months: "0", points: "0", title: "Failure to stop at Stop Sign"}

My current code, as I've explained it in the post:

<div className="outer-content">
    {chargesData && chargesData.length > 0 ? (
        chargesData.map((cat) => (
            <div className="inner-content">
                <Typography style={{ color: '#fff', wordBreak: 'break-word' }} variant="h6" gutterBottom>{cat.category}</Typography>
                <div className="inner-content-body" style={{ flexDirection: 'row', flexWrap: 'wrap', flex: '0', overflowY: 'unset', paddingLeft: '1.5%' }}>
                    {cat.charges && cat.charges.length > 0 ? (
                        cat.charges.map((charge) => (
                            <Typography style={{ color: '#fff', wordBreak: 'break-word', textAlign: 'center' }} variant="body1" gutterBottom>{charge.title}</Typography>
                            <Typography style={{ color: '#fff', wordBreak: 'break-word', textAlign: 'center' }} variant="body2" gutterBottom>{charge.months !== undefined ? charge.months : '0'} months</Typography>
                            <Typography style={{ color: '#fff', wordBreak: 'break-word', textAlign: 'center' }} variant="body2" gutterBottom>{charge.fine !== undefined ? charge.fine : '$0.0'}</Typography>
                            <Typography style={{ color: '#fff', wordBreak: 'break-word', textAlign: 'center' }} variant="body2" gutterBottom>{charge.points !== undefined ? charge.points : '0'} point(s)</Typography>
                            ))
                    ) : (
                        <></>
                    )}
                </div>
            </div>
        ))
    ) : (
    <></>
)}
</div>

Hopefully someone has the answer, thanks again for reading.

Kind regards.

CodePudding user response:

Keep you filter string on state

const [chargeTitleSearch, setChargeTitleSearch] = useState("");

Then you can create the filter function

const filterFn = t => !chargeTitleSearch || t.match(chargeTitleSearch); // or whatever

Then use the filter

cat.charges.filter(c => filterFn(c.title)).map(...);

If you want to omit any categories that have no data after filtering:

// Make a new list with the charges in each category filtered out
const filterChargeData = chargesData.map(c => {
  return { ...c, charges: c.charges.filter(cc => filterFn(cc.title))};
});

// Filter the categories based on whether or not they contain any charges.
const nonEmptyCategories = filterChargeData.filter(c => c.charges.length);
  • Related