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.
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'],
);
}
$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.
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);