I'm trying to .map()
an object of arrays to create a div
for each key/value pair. Here is a sample of the object format:
const data = {
year: ["2018", "2020"],
make: ["Honda"],
model: ["Accord", "Civic"],
subModel: []
}
Here is what I have:
const filterChips = Object.entries(data)
.flatMap(([key, value]) => [value].flat()
.filter(v => v !== "" && v !== null)
.map(v => [key, v]))
.map(it => (<div>{it}</div>));
Which gives me the output:
<div>year2018</div>
<div>year2020</div>
<div>makeHonda</div>
<div>modelAccord</div>
<div>modelCivic</div>
Which is almost what I want, but I would like to be able to separate the key/value in each div
so last line of code is:
.map(it => (<div>{it.key}: {it.value}</div>));
So that the output would be:
<div>year: 2018</div>
<div>year: 2020</div>
<div>make: Honda</div>
<div>model: Accord</div>
<div>model: Civic</div>
I feel like I'm close, but tuck on the last part...
You can use an inner .map()
on your inner vals
arrays to map htem divs, and then return these array of divs from your .flatMap()
to merge all them together into one array. There is no need to create a wrapper array [value]
and call .flat()
on that:
const filterChips = Object.entries(data).flatMap(([key, vals]) =>
vals.map(val => <div>{key}: {val}</div>)
);
To incorporate a filter, you can filter out before you .map()
:
vals.filter(val => val !== "" && val !== null).map(val => <div>{key}: {val}</div>)
Runnable Example:
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.3.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.3.1/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@babel/[email protected]/babel.min.js"></script>
<script type="text/babel">
const data = {
year: ["2018", "2020"],
make: ["Honda"],
model: ["Accord", "Civic"],
subModel: []
};
const filterChips = Object.entries(data).flatMap(([key, vals]) =>
vals.map(val => <div>{key}: {val}</div>
));
ReactDOM.createRoot(document.body).render(<React.Fragment>{filterChips}</React.Fragment>);
setTimeout(() => {
console.log(document.body.innerHTML);
}, 0);
</script>