Closed. This question needs to be more
focused. It is not currently accepting answers.
Answer
Solution:
try uasort - it'll sort an array with a user-defined comparison function and maintain index association:
<?php
$x = [
0 =>[
'member_reference_identifier' => '001',
'user_status' => 'Hold',
'is_primary' => 'true',
],
1 => [
'member_reference_identifier' => '002',
'user_status' => 'Banned',
'is_primary' => 'true',
],
2 => [
'member_reference_identifier' => '003',
'user_status' => 'Banned',
'is_primary' => 'true',
],
3 =>[
'member_reference_identifier' => '004',
'user_status' => 'Active',
'is_primary' => 'false',
],
4 => [
'member_reference_identifier' => '005',
'user_status' => 'Active',
'is_primary' => 'true',
],
5 => [
'member_reference_identifier' => '006',
'user_status' => 'Hold',
'is_primary' => 'true',
],
6 => [
'member_reference_identifier' => '007',
'user_status' => 'Banned',
'is_primary' => 'true',
],
];
function sorter($a,$b){
$states = ['Active'=>0,'Hold'=>1,'Banned'=>2];
if ($a['is_primary'] == 'true' && $b['is_primary']=='false') return -1;
if ($a['is_primary'] == 'false' && $b['is_primary']=='true') return 1;
return $states[$a['user_status']]<=>$states[$b['user_status']];
}
uasort($x,'sorter');
print_r($x);
PS your array was inconsistent - i've unified keys user. account_status to user_status.
Answer
Solution:
You could use collection's sortBy method.
$array = array(
0 =>
array(
'member_reference_identifier' => '001',
'user_status' => 'Hold',
'is_primary' => 'true',
),
1 =>
array(
'member_reference_identifier' => '002',
'user_status' => 'Banned',
'is_primary' => 'true',
),
2 =>
array(
'member_reference_identifier' => '003',
'user' => 'Banned',
'is_primary' => 'true',
),
3 =>
array(
'member_reference_identifier' => '004',
'user_status' => 'Active',
'is_primary' => 'false',
),
4 =>
array(
'member_reference_identifier' => '005',
'user_status' => 'Active',
'is_primary' => 'true',
),
5 =>
array(
'member_reference_identifier' => '006',
'user_status' => 'Hold',
'is_primary' => 'true',
),
6 =>
array(
'member_reference_identifier' => '007',
'user_status' => 'Banned',
'is_primary' => 'true',
),
);
collect($array)
->sortBy(function ($item) {
if (!isset($item['user_status'] || !isset($item['is_primary'])) {
return 7;
} elseif ($item['user_status'] == 'Active' && $item['is_primary'] == 'true') {
return 1;
} elseif ($item['user_status'] == 'Hold' && $item['is_primary'] == 'true') {
return 2;
} elseif ($item['user_status'] == 'Banned' && $item['is_primary'] == 'true') {
return 3;
} elseif ($item['user_status'] == 'Active' && $item['is_primary'] == 'false') {
return 4;
} elseif ($item['user_status'] == 'Hold' && $item['is_primary'] == 'false') {
return 5;
} elseif ($item['user_status'] == 'Banned' && $item['is_primary'] == 'false') {
return 6;
} else {
return 7;
}
})
->values()
->all();
What I'm doing in the Closure is assigning a number to each possibility. This number is what the sortBy method will use to sort the data.
You could also use LazyCollections instead of Collections. The logic stays the same for the most part.
use Illuminate\Support\LazyCollection;
$sorted = LazyCollection::make($array)->sortBy(function ($item) {
...
})
->values()
->all();
Answer
Solution:
Using a slightly modified version of pQd's sorter function will give you what you want.
First we need to incorporate the is_primary field value by giving true a value of 1 and false -1 and then multiply it with both values from the states array before returning the result to the "uasort" function. We also need to modify the states array shifting it one to the right to eliminate the zero because it will always give zero when multiplied with either a negative or a positive number.
I didn't test this but it should work if there are no typos.
function sorter($a,$b){
$is_primary = ['true' =>-1, 'false' =>1] // using true =1, false=-1 will reverse is_primary order
$states = ['Active'=>1,'Hold'=>2,'Banned'=>3];
$c=$is_primary[$a['is_primary']];
$d=$is_primary[$b['is_primary']];
$e=$states[$a['user_status']];
$f=$states[$b['user_status']];
return (e*$c)<=>(f*$d);
}
uasort($the_array,'sorter');
print_r($the_array);
The above is the same as the below. I edited it breaking it down for better readability and understanding:
function sorter($a,$b){
$is_primary = ['true' =>-1, 'false' =>1]
$states = ['Active'=>1,'Hold'=>2,'Banned'=>3];
return $states[$a['user_status']]*$is_primary[$a['is_primary']] <=>$states[$b['user_status']]*$is_primary[$b['is_primary']];
}
uasort($the_array,'sorter');
print_r($the_array);
Note that those with is_primary = false will be reversed in term of the status criteria order but that should be easy to fix inside the sorter function by for example initalizing the array iniside an IF statement reversing the values whenever both is_primary fields of $a and $b are false 1,2,3 to 3,2,1 but I'm not sure, you need to inspect the underlying sorting algorithm of the uasort function.
Source