Bham
Bham

Reputation: 319

PHP create array based on date

I'm trying to create an dynamic array sorted on date. Let me try to explain. I've the follow user array

    $users = [
        0 => [
            'user_id' => 1,
            'user_date' => '2017-04-26',
            'user_name' => 'test',
        ],
        1 => [
            'user_id' => 2,
            'user_date' => '2017-04-26',
            'user_name' => 'test 2',
        ],
        2 => [
            'user_id' => 3,
            'user_date' => '2017-04-28',
            'user_name' => 'test 3',
        ]
    ];

While looping throug this array a want to group the users that has the same date. An example how the output should look like

Array
(
    [0] => Array
        (
            [DATE] => 2017-04-26
            [USERS] => Array
                (
                    [0] => Array
                        (
                            [user_id] => 1
                            [user_title] => test
                        )

                    [1] => Array
                        (
                            [user_id] => 2
                            [user_title] => test 2
                        )

                )

        )

    [1] => Array
        (
            [DATE] => 2017-04-28
            [USERS] => Array
                (
                    [0] => Array
                        (
                            [user_id] => 4
                            [user_title] => test 4
                        )

                )

        )

)

I have tried to do some things in a foreach loop but could not make this get to work.

    $result = array();
    $i = 0;

    // Start loop
    foreach ($users as $user) {
        // CHECK IF DATE ALREADY EXISTS
        if(isset($result[$i]['DATE']) && $result[$i]['DATE'] == $user['user_date']){
            $i++;
        }

        // FILL THE ARRAY
        $result[$i] = [
            'DATE' => $user['user_date'],
            'USERS' => [
                'user_id' => $user['user_id'],
                'user_title' => $user['user_name'],
            ]
        ];
    }

I've changed it a little bit to this:

   foreach ($users as $user => $properties) {
        foreach ($properties as $property => $value) {
            if($property == 'user_date'){
                if(empty($result[$value])){
                    $result[$i] = [];
                }
                $result[$i][] = [
                    'user_id' => $properties['user_id'],
                    'user_name' => $properties['user_name'],
                ];

                $i++;
            }
        }
    }

But how could i change the start keys (dates) to numbers equal to 0, 1 etc.

Upvotes: 0

Views: 259

Answers (3)

printfmyname
printfmyname

Reputation: 971

There are few ways to tackle your question. I always prefer to use PHP built-in function, as there are a lot of them. This answer uses a PHP builtin function usort to sort your array in place. It takes two arguments, you array and a comparator function. usort will parse two array object to comparator function. If you dont know about compactor functions, a Comparator compare these two objects and return a integer 1, 0, or -1 which tells if first object is greater, equal or less than second object, respectively. So pass in a comparator function to that takes care of the comparation of dates.

$users = [
    0 => [
        'user_id' => 1,
        'user_date' => '2017-04-25',
        'user_name' => 'test',
    ],
    1 => [
        'user_id' => 2,
        'user_date' => '2017-04-26',
        'user_name' => 'test 2',
    ],
    2 => [
        'user_id' => 3,
        'user_date' => '2017-04-28',
        'user_name' => 'test 3',
    ],
    3 => [
        'user_id' => 4,
        'user_date' => '2017-04-28',
        'user_name' => 'test 4',
    ],
    4 => [
        'user_id' => 5,
        'user_date' => '2017-04-26',
        'user_name' => 'test 5',
    ],
];

usort($users, function($user1, $user2){
    // This function sort users by ascending order of date. Compares date. if user 1 has later date than user 2, place him on the bottom of the array
    return strtotime($user1['user_date']) > strtotime($user2['user_date']);
});
var_dump($users);

Upvotes: 0

Jeremy
Jeremy

Reputation: 521

If you want the exact output you showed (honestly, I like Ryan's answer better):

$result = array();
$i = 0;

// Start loop
foreach ($users as $user) {
    // CHECK IF DATE ALREADY EXISTS AND IS NOT IN THE SAME GROUP
    if (isset($result[$i]['DATE']) && $result[$i]['DATE'] != $user['user_date']){
        $i++;
    }

    // STARTING A NEW GROUP
    if(!isset($result[$i])) {
        $result[$i] = array(
            'DATE' => $user['user_date'],
            'USERS' => array()
        );
    }


    // FILL THE ARRAY (note the ending [] to add a new entry in this group's USERS array)
    $result[$i]['USERS'][] = array(
        'user_id' => $user['user_id'],
        'user_title' => $user['user_name'],
    );
}

Upvotes: 1

Ryan Tuosto
Ryan Tuosto

Reputation: 1951

$users = [
        0 => [
            'user_id' => 1,
            'user_date' => '2017-04-26',
            'user_name' => 'test',
        ],
        1 => [
            'user_id' => 2,
            'user_date' => '2017-04-26',
            'user_name' => 'test 2',
        ],
        2 => [
            'user_id' => 3,
            'user_date' => '2017-04-28',
            'user_name' => 'test 3',
        ]
    ];

$sorted = [];

foreach ($users as $user => $properties) {
   foreach ($properties as $property => $value) {
      if ($property =='user_date') {
          if (empty($sorted[$value])) {
            $sorted[$value] = [];
          }
          $sorted[$value][] = $users[$user];
      }
   }
}

var_dump($sorted);

Do a nested loop through your arrays and then check for the unique value you're looking for (in this case the user_date) and add that as a key in your sorted array. If the key exists add a new item (user) to that key, otherwise make the new key first. This way you have an array of dates each containing an array of users with that date.

Upvotes: 2

Related Questions