Procházejte pole objektů a zobrazte je v komponentě reakce

Mám pole objektů následovně. Data jsou založena na created_date pro např. („2021-09-12“)

Jak vidíte, mám data za posledních 5 dní. tj. 12. září, 11. září, 10. září, 9. září a 8. září. Odpověď neobsahuje žádná data pro 11. září a 8. září.

const buildData = [
    {
      "project_id": "1H16SET9829",
      "created_date": "2021-09-12",
      "status": "P"
    },
    {
      "project_id": "1J01SET10974",
      "created_date": "2021-09-10",
      "status": "F"
    },
    {
      "project_id": "1J01SET10971",
      "created_date": "2021-09-09",
      "status": "P"
    },
    {
      "project_id": "1J01SET10969",
      "created_date": "2021-09-09",
      "status": "F"
    }
]

Na základě těchto výše uvedených informací musím zobrazit data v uživatelském rozhraní pomocí funkční komponenty reagovat následovně

  Sep 12, 2021  | Sep 11,2021 |   Sep 10, 2021   |   Sep 09, 2021    | Sep 08, 2021
1H16SET9829 (P) |             | 1J01SET10974 (F) | 1J01SET10971 (P)  |
                |             |                  | 1J01SET10971 (F)  |

Může mi prosím někdo dát vědět, jak toho dosáhnout. Zkoušel jsem následující, ale nezobrazuje správná data. Nechápu, jak správně zobrazit project_id pod jeho datem. Některá data mají také 2 project_ids. pro např. Září 09,2021 má 2 project_id a obě je třeba zobrazit pod sebou a poté pokračovat dalším datem.

const renderProjects = (props) => {
    const items = buildData.map( (t, idx) => (
        <>
          <div>{ t.created_date }</div>
          <div>{t.project_id</div>
        </>
    ))

    return (
        <div className="project-list">
            { items }
        </div>
    )
}

Odpověď

Můžete udělat něco takového (viz vložené komentáře):

const buildData = [
    {
        project_id: '1H16SET9829',
        created_date: '2021-09-12',
        status: 'P',
    },
    {
        project_id: '1J01SET10974',
        created_date: '2021-09-10',
        status: 'F',
    },
    {
        project_id: '1J01SET10971',
        created_date: '2021-09-09',
        status: 'P',
    },
    {
        project_id: '1J01SET10969',
        created_date: '2021-09-09',
        status: 'F',
    },
];

export const RenderProjects = (props) => {
    // convert the buildData into a map from date -> list of `{project_id, status}`s
    const buildDataByDate = buildData.reduce((map, project) => {
        const projectInfo = {
            project_id: project.project_id,
            status: project.status,
        };
        if (!map[project.created_date]) {
            map[project.created_date] = [projectInfo];
        } else {
            map[project.created_date].push(projectInfo);
        }
        return map;
    }, {});


    // find the first and last dates
    const minDate = Object.keys(buildDataByDate).sort()[0];
    const maxDate = Object.keys(buildDataByDate).sort().reverse()[0];
    // find how many days are between them
    const daysBetween =
        (Date.parse(maxDate) - Date.parse(minDate)) / (24 * 60 * 60 * 1000);
    // add in the missing dates
    [...Array(daysBetween).keys()].forEach((increment) => {
        const dateToAdd = new Date(
            Date.parse(minDate) + increment * 24 * 60 * 60 * 1000,
        )
            .toISOString()
            .substring(0, 10);
        if (!buildDataByDate[dateToAdd]) {
            buildDataByDate[dateToAdd] = [];
        }
    });

    // render something for each entry in that map
   const items = Object.entries(buildDataByDate)
        .sort((a, b) => {
            return Date.parse(b[0]) - Date.parse(a[0]);
        })
        .map(([date, projects]) => {
            return (
                <React.Fragment key={date}>
                    <div>{date}</div>
                    {projects.map((project) => {
                        return (
                            <div
                                key={project.project_id}
                            >{`${project.project_id} (${project.status})`}</div>
                        );
                    })}
                </React.Fragment>
            );
        });

    return <div className='project-list'>{items}</div>;
};