Search code examples
phparraysreact-nativeapireact-native-sectionlist

How to simplify the formatting array list data in php API to feed React Native section list


Good day! I am writing RestAPI using php. My team member is consuming the API using React-native, He requested that I should format the response in the Format bellow

{
        title: 'Class of 2007',
        data: [
            { id: 1, lastsName: 'Igbashio', firstName: 'Kalifort', middleName: 'Kashimana', email: 'igbashiokalifortkashimana@gmail.com', image: 'https://img.freepik.com/premium-photo/young-student-caucasian-woman-isolated-white-background-pointing-side-present-product_1368-289762.jpg?w=740' },
            { id: 2, lastsName: 'Usman', firstName: 'Bello', middleName: '', email: 'usmanbello@gmail.com', image: 'https://img.freepik.com/free-photo/waist-up-portrait-handsome-serious-unshaven-male-keeps-hands-together-dressed-dark-blue-shirt-has-talk-with-interlocutor-stands-against-white-wall-self-confident-man-freelancer_273609-16320.jpg?size=626&ext=jpg&ga=GA1.2.1337949710.1669025188' },
            { id: 3, lastsName: 'Manasseh', firstName: 'Isa', middleName: '', email: 'manassehisa@gmail.com', image: 'https://img.freepik.com/free-photo/young-attractive-handsome-guy-feels-delighted-gladden-amazed_295783-535.jpg?size=626&ext=jpg&ga=GA1.2.1337949710.1669025188' }
        ]
    },
    {
        title: 'Class of 2008',
        data: [
            { id: 4, lastsName: 'Igbashio', firstName: 'Sansa', middleName: 'Sewuese', email: 'igbashiosansaswewuese@gmail.com', image: 'https://img.freepik.com/free-photo/front-view-female-student-white-shirt-black-jacket-wearing-backpack-holding-files-with-copybooks-blue-wall-college-university-lessons_140725-43393.jpg?size=626&ext=jpg&ga=GA1.2.1337949710.1669025188' },
            { id: 5, lastsName: 'Yusuf', firstName: "Sa'atu", middleName: '', email: 'yusufsaatu@gmail.com', image: 'https://img.freepik.com/free-photo/cheerful-muslim-woman_53876-14375.jpg?w=360&t=st=1669732335~exp=1669732935~hmac=9942e2842661b423d7686f2ba66d87b2b9485e95f438b415993b38e910203937' },
            { id: 6, lastsName: 'Rimamtse', firstName: 'Bleesing', middleName: 'Fxiafatirimam', email: 'rimamblessing@gmail.com', image: 'https://img.freepik.com/premium-photo/smiling-black-woman-striped-shirt-with-arms-crossed_33839-10129.jpg?size=626&ext=jpg&ga=GA1.2.1337949710.1669025188' }
        ]
    },

In order to use in react-native sectionList. Below is how I achieved the task so far

$list = Members::where(function ($sql) use ($input) {
            if (isset($input["search"])) :
                return $sql->where('regNo', 'LIKE', $input["search"])->orWhere('lastsName', 'LIKE', $input["search"])
                    ->orWhere('firstName', 'LIKE', $input["search"])->orWhere('email', 'LIKE', $input["search"])
                    ->orWhere('phone', 'LIKE', $input["search"])->orWhere('gender', 'LIKE', $input["search"]);
            endif;
        })->orderBy('graduateYear', 'DESC')->orderBy('lastsName', 'ASC')->skip($input["start"])->take($input["length"])->get();
die(json_encode(formatMembers($list)));


private function formatMembers($list)
    {
        $json = array();
        $i = 0;
        $lastYear = null;
        foreach ($list as $x) {
            if (count($json) == 0) :
                $json[$i]["title"] = $x->graduateYear;
                $json[$i]['data'][] = array(
                    "id" => $x->id, "lastsName" => $x->lastsName, "firstName" => $x->firstName,
                    "middleName" => $x->middleName, "email" => $x->email, "image" => null
                );
                $lastYear = $x->graduateYear;
            else:
                if ($lastYear == $x->graduateYear) :
                    $json[$i]['data'][] = array(
                        "id" => $x->id, "lastsName" => $x->lastsName, "firstName" => $x->firstName,
                        "middleName" => $x->middleName, "email" => $x->email, "image" => null
                    );
                    $lastYear = $x->graduateYear;
                else :
                    $i++;
                    $json[$i]["title"] = $x->graduateYear;
                    $json[$i]['data'][] = array(
                        "id" => $x->id, "lastsName" => $x->lastsName, "firstName" => $x->firstName,
                        "middleName" => $x->middleName, "email" => $x->email, "image" => null
                    );
                    $lastYear = $x->graduateYear;
                endif;
            endif;
        }
        return $json;
    }

Bellow is the result of my implementation

[
        {
            "title": "2016",
            "data": [
                {
                    "id": 6,
                    "lastsName": "Igbashio ",
                    "firstName": "Sansa",
                    "middleName": "Seember",
                    "email": "sansaigbashio@Gmail.com",
                    "image": null
                },
                {
                    "id": 7,
                    "lastsName": "Usman",
                    "firstName": "Smith",
                    "middleName": "",
                    "email": "smithusman@Gmail.com",
                    "image": null
                }
            ]
        }]

My question is there a better way of achieving this? considering when dealing with a large number of records or even a shorter method. Any ideal will be welcome. Thank you in advance!


Solution

  • Use temporary first-level associative keys to assist in grouping. When finished iterating, remove the first-level keys with array_values();

    Code: (Demo)

    $grouped = [];
    foreach ($array as $obj) {
        sscanf($obj->graduateYear, 'Class of %d', $year);
        unset($obj->graduateYear);
        $grouped[$year]['title'] = $year;  // doesn't matter that this is overwritten over and over
        $grouped[$year]['data'][] = $obj;
    }
    var_export(array_values($grouped));
    

    Please also heed the warning here regarding mutating objects inside of a foreach loop.