I have this array that has this structure please check the code down below , my end results should look like the following :
- veg
- apple
- carrot
- meat
- chicken
- steak
my current results are
apple carrot chicken steak
since I cannot structure the array other wise and don't want to go in to deep nesting or even nest loops which I doubt it will work in react any idea how to achieve the previous results using map , where I map through group only once to create the group name and to then add the items related to that group inside that group?, food for thought : could conditional rendering be also leveraged here ? I was able to only get either the group multiple times or the items only..
const arr = {
itmes: [
{ id: 1, group: "veg", item: "apple" },
{ id: 2, group: "veg", item: "carrot" },
{ id: 3, group: "meat", item: "chicken" },
{ id: 4, group: "meat", item: "steak" }
]
};
function App() {
return (
<div>
{arr["itmes"].map(
(item) => item.group
//item.item
)}
</div>
);
}
CodePudding user response:
Option 1
First, make sure your array is sorted by Group:
const sorted = arr["itmes"]
.sort((a, b) => (a.group || '').localeCompare(b.group));
Then you can render and conditionally add another heading element whenever the group name changes:
<ul>
{data.map((d, id) => (
<>
((id > 0 || d.group !== data[id - 1].group) ? <li key={`${id}-h`}><b>{d.group}</b></li> : undefined)
<li key={`${id}-v`}>{d.item}</li>
</>
))}
</ul>
Extra: Custom group sorting
If you need to custom sort the array according to another array:
const sortLtu = ['veg', 'apple', 'meat'];
data.sort((a, b) => sortLtu.indexOf(a.group) - sortLtu.indexOf(b.group));
Option 2: Util function
If you end u doing this often you may create a util function:
Array.prototype.groupBy = function(cb) {
const groups = [];
this.forEach((d, id, arr) => {
const g = cb(d, id, arr);
let group = groups.find(_g => _g.group === g);
if (!group) {
group = { group: g, items: [] };
groups.push(group);
}
group.items.push(d);
})
return groups;
}
And then use it like
{data.groupBy(i => i.group).map((bundle, ix) => (
<div key={ix}>
<b>{bundle.group}</b>
<ul>
{bundle.items.map((item, ix) => <li key={ix}>{item.item}</li>)}
</ul>
</div>
))}