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> ); }
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.