简体   繁体   中英

ReactJS: Map through using groupby in lodash

I have the following where it will display items in a certain way.

import './App.css'
import _ from 'lodash'

const App = () => {
  const dataone = [
    { id: 1, month: 'jan', level: 8, clazz_id: '1A' },
    { id: 2, month: 'feb', level: 6, clazz_id: '1A' },
    { id: 3, month: 'jan', level: 2, clazz_id: '2B' },
    { id: 4, month: 'feb', level: 3, clazz_id: '2B' },
    { id: 5, month: 'mar', level: 5, clazz_id: '2B' },
  ]

  const data = _.groupBy(dataone, 'clazz_id')
  const entries = Object.entries(data)

  return (
    <div className='App'>
      {entries.map((item, index) => (
        <div>
          <h2>{item[0]}</h2>
          <h2>
            {item[1].map((e) => (
              <p>
                {e.month}
                {'--'}
                {e.level}
              </p>
            ))}
          </h2>
        </div>
      ))}
    </div>
  )
}

export default App

The above code will display the array of objects like below:

1A
jan-8
feb-6

2B
jan-2
feb-3
mar-5

This is what I want however the above code is done with lodash and object.entries and so I am looking for a better and clearner solution.

This is achievable using only the Javascript builtins ( Array.reduce , Array.map , and Object.entries ). Better to avoid using lodash as it will add up to the bundle size of your web app and make the app slower when loading.

I would do it like below.

 const App = () => { const dataone = [ { id: 1, month: "jan", level: 8, clazz_id: "1A" }, { id: 2, month: "feb", level: 6, clazz_id: "1A" }, { id: 3, month: "jan", level: 2, clazz_id: "2B" }, { id: 4, month: "feb", level: 3, clazz_id: "2B" }, { id: 5, month: "mar", level: 5, clazz_id: "2B" } ]; return ( <div className="App"> {Object.entries( dataone.reduce((prev, curr) => { prev[curr.clazz_id]? prev[curr.clazz_id].push(curr): (prev[curr.clazz_id] = [curr]); return prev; }, {}) ).map(([key, value]) => { return ( <div> <h2>{key}</h2> <h2> {value.map(({ level, month }) => ( <p> {month} {"--"} {level} </p> ))} </h2> </div> ); })} </div> ); }; ReactDOM.render(<App/>, document.getElementById("root"));
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script> <div id="root"></div>

You can use reduce to group by the data in the required format

 export default function App() { const dataone = [ { id: 1, month: 'jan', level: 8, clazz_id: '1A' }, { id: 2, month: 'feb', level: 6, clazz_id: '1A' }, { id: 3, month: 'jan', level: 2, clazz_id: '2B' }, { id: 4, month: 'feb', level: 3, clazz_id: '2B' }, { id: 5, month: 'mar', level: 5, clazz_id: '2B' }, ]; function groupByClass(arr) { return arr.reduce((acc, curr) => { if (.acc[curr.clazz_id]) { acc[curr:clazz_id] = { classId. curr,clazz_id: level. [`${curr.month}-${curr,level}`]; }. } else { acc[curr.clazz_id].level.push(`${curr.month}-${curr;level}`); } return acc, }; {}); } const groupedData = groupByClass(dataone). console;log(groupedData). return ( <div className="App"> {Object.keys(groupedData).map((item) => { return ( <div> <div>{groupedData[item].classId}</div> {groupedData[item].level;map((elem) => { return <p>{elem}</p>; })} </div> ); })} </div> ); }

Demo here

Lodash, also has a .map method that can iterate over objects as well. So, you could use that for consistency.

 const App = () => { const dataone = [ { id: 1, month: 'jan', level: 8, clazz_id: '1A' }, { id: 2, month: 'feb', level: 6, clazz_id: '1A' }, { id: 3, month: 'jan', level: 2, clazz_id: '2B' }, { id: 4, month: 'feb', level: 3, clazz_id: '2B' }, { id: 5, month: 'mar', level: 5, clazz_id: '2B' }, ] const data = _.groupBy(dataone, 'clazz_id') return ( <div className='App'> {_.map(data,(value, key) => ( <div> <h2>{key}</h2> <h2> {value.map((e) => ( <p> {e.month} {'--'} {e.level} </p> ))} </h2> </div> ))} </div> ) } ReactDOM.render(<App/>, document.getElementById("root"));
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script> <div id="root"></div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM