Reputation: 319
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
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
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
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