I'm quite new to both react and JavaScript and would really appreciate some advice on this. I want to iterate through a nested array like the one below by using the map() method:
const demos = [
{
id : '1',
name: 'name1',
dates: ['jan', 'feb', 'apr']
},
{
id : '2',
name: 'name2',
dates: ['feb', 'may']
}
];
I want to first map through the first object with the first date and then the second date and so on, before going to the next object and then sort it based on date to ideally achieve the following output:
name1: jan
name1: feb
name2: feb
name1: apr
name2: may
The only not quite working solution I've come up with this far is:
import * as React from 'react';
const demos = [
{id : '1',
name: 'name1',
dates: ['jan', 'feb', 'apr']
},
{id : '2',
name: 'name2',
dates: ['feb', 'may']
}
];
const counts = ['0','1','2'];
export default function Test() {
return (
<div>
{
counts.map(count => (
demos.map(demo =>(
<div key={demo.id}>
<div>{demo.name}: {demo.dates[count]}</div>
</div>
))
))
}
</div>
);
}
which gives me the following output:
name1: jan
name2: feb
name1: feb
name2: may
name1: apr
name2:
using the const counts
isn't really working and doesn't feel like the proper way to begin with. How can I do this in a good way and then sort it by date ?
Sorted
const App = () => {
const demos = [
{ id: "1", name: "name1", dates: ["jan", "feb", "apr"] },
{ id: "2", name: "name2", dates: ["feb", "may"] }
];
const monthIdx = {
jan: 1,
feb: 2,
mar: 3,
apr: 4,
may: 5,
jun: 6,
jul: 7,
aug: 8,
sep: 9,
oct: 10,
nov: 11,
dec: 12
};
const sortedDemo = demos
.map((demo) => {
return demo.dates.map((date) => ({ [demo.name]: date }));
})
.flat()
.sort((a, b) => {
const monthA = Object.values(a)[0];
const monthB = Object.values(b)[0];
return monthIdx[monthA] - monthIdx[monthB];
});
return sortedDemo.map((demo) => {
const [key] = Object.entries(demo);
const [name, date] = key;
return (
<div>
{name} - {date}
</div>
);
});
};
Without sort
const demos = [
{ id: "1", name: "name1", dates: ["jan", "feb", "apr"] },
{ id: "2", name: "name2", dates: ["feb", "may"] }
];
return demos.map((demo) => {
return demo.dates.map((date) => (
<div>
{demo.name} - {date}
</div>
));
});
One is able to provide a workable code using stack-snippets like below:
const demos = [
{id : '1',
name: 'name1',
dates: ['jan', 'feb', 'apr']
},
{id : '2',
name: 'name2',
dates: ['feb', 'may']
}
];
// const counts = ['0','1','2'];
function Test() {
const sortHelper = Object.fromEntries(("jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec")
.split(", ").map((m, idx) => ([m, idx])));
const transformArr = arr => (
[...arr].map(({name, dates}) => (
dates.map(month => ({ name, month }))
))
.flat()
.sort((a, b) => (sortHelper[a.month] - sortHelper[b.month]))
);
return (
<div>
{
transformArr(demos).map(({name, month}) => (
<div>{name}: {month}</div>
))
}
</div>
);
}
ReactDOM.render(
<div>
DEMO
<Test />
</div>,
document.getElementById("rd")
);
<div id="rd"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
Explanation
sortHelper
object is created.map
and de-structure name
, dates
dates
to create an object with two props name
, month
.flat()
to remove nested arrays.sort()
in conjunction with sortHelper
to provide the necessary orderImplement the following code into your
{demo.name}: {`demo.dates.map((e) => {e} )`} It should works.