Reputation: 45
I have an array with date, status and summ:
Array
(
[0] => Array
(
[date] => 2019-07-06 14:01:52
[status] => paid
[summ] => 100
)
[1] => Array
(
[date] => 2019-07-02 12:22:31
[summ] => 320
[status] => pending
)
[2] => Array
(
[date] => 2019-07-01 18:43:58
[summ] => 100
[status] => pending
)
[3] => Array
(
[date] => 2019-06-26 14:01:52
[status] => canceled
[summ] => 200
)
i need to sort this array by status first (1.pending, 2.paid, 3.canceled), and then by date (new at the top).
Order which i nedd:
pending 2019-07-02 12:22:31 pending 2019-07-01 18:43:58 paid 2019-07-06 14:01:52 canceled 2019-06-26 14:01:52
with date i don't have any problems:
usort($new11, function($a, $b) {
return strtotime($b['date']) - strtotime($a['date']);
});
But how to sort by status in order which i need?
Thanx:)
Upvotes: 1
Views: 807
Reputation: 1381
you can use Spaceship:
<?php
$new11 = [
[
'date' => '2019-07-06 14:01:52',
'status' => 'paid',
'summ' => 100,
],
[
'date' => '2019-07-02 12:22:31',
'status' => 'pending',
'summ' => 320,
],
[
'date' => '2019-07-01 18:43:58',
'status' => 'pending',
'summ' => 100,
],
[
'date' => '2019-06-26 14:01:52',
'status' => 'canceled',
'summ' => 200,
],
];
$pending = 3;
$paid = 2;
$canceled = 1;
usort($new11, function($a, $b) use ($pending, $paid, $canceled) {
return (${$b['status']} <=> ${$a['status']}) * 10 +
(strtotime($b['date']) <=> strtotime($a['date']));
});
var_dump($new11);
Upvotes: 0
Reputation: 24276
You can simply use array_multisort to achieve it:
$test = [
[
'date' => '2019-07-06 14:01:52',
'status' => 'paid',
'summ' => 100,
],
[
'date' => '2019-07-02 12:22:31',
'status' => 'pending',
'summ' => 320,
],
[
'date' => '2019-07-01 18:43:58',
'status' => 'pending',
'summ' => 100,
],
[
'date' => '2019-06-26 14:01:52',
'status' => 'canceled',
'summ' => 200,
],
];
array_multisort(
array_column($test, 'status'),
SORT_DESC,
array_column($test, 'date'),
SORT_DESC,
$test
);
var_dump($test);
The result would be:
array(4) {
[0]=>
array(3) {
["date"]=>
string(19) "2019-07-02 12:22:31"
["status"]=>
string(7) "pending"
["summ"]=>
int(320)
}
[1]=>
array(3) {
["date"]=>
string(19) "2019-07-01 18:43:58"
["status"]=>
string(7) "pending"
["summ"]=>
int(100)
}
[2]=>
array(3) {
["date"]=>
string(19) "2019-07-06 14:01:52"
["status"]=>
string(4) "paid"
["summ"]=>
int(100)
}
[3]=>
array(3) {
["date"]=>
string(19) "2019-06-26 14:01:52"
["status"]=>
string(8) "canceled"
["summ"]=>
int(200)
}
}
Upvotes: 3
Reputation: 17805
You are almost there. You could have an array of priority with values assigned. Then, you could do simple math operations to judge the result.
<?php
usort($new11, function($a, $b) {
$priority = [
'pending' => 1,
'paid' => 2,
'canceled' => 3
];
$result = $priority[$a['status']] - $priority[$b['status']];
if($result === 0) return strtotime($b['date']) - strtotime($a['date']);
return $result;
});
Upvotes: 0