skip to Main Content

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…

2

Answers


  1. reducers give you a lot more flexibility.

    const filterChips  = Object.entries(data).reduce((acc, [key, value])=>{
      for(const v of value){
        acc.push((<div>{key}: {v}</div>))
      }
    return acc
    }, [])
    
    Login or Signup to reply.
  2. You can use an inner .map() your inner vals arrays to divs, and then return this from your .flatMap() to merge all the mapped divs into one array. No need to create a wrapper div 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>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search