I have the following code:
$check = array('person a','person c');
$data = array('person c','person a','person d','person e');
define('check',$check);
//asort($data);
print'<pre>';print_r($data);print'</pre>';
usort($data,function($a,$b){
return empty(check[$a]) ? 1 : $a <=> $b;
});
print'<pre>';print_r($data);print'</pre>';
exit;
What I am trying to achieve is:
person d
person e
person a
person c
What I get is
person e
person a
person d
person c
Because person a and c are in the $check
array, I'm trying to sort my array based on alphabetically for those not in the $check group and then those who are. I could probably split things up a bit and am not overly familiar with the usort
custom functions, but is it possible to acheive it this way?
CodePudding user response:
Create a "mapping" array using array_map()
and in_array()
to flag each $data
item, then array_multisort()
both the mapping array and the $data
array:
<?php
$check = array('person a','person c');
$data = array('person c','person a','person d','person e');
function dmap ($itm) {
GLOBAL $check;
return ((int)in_array($itm, $check) 1) . $itm;
}
$mm = array_map('dmap', $data);
array_multisort($mm, $data);
print_r($data);
exit;
Outputs:
Array
(
[0] => person d
[1] => person e
[2] => person a
[3] => person c
)
When providing two arrays to array_multisort()
the function sorts the first array, ascending by default, and applies the sorted order of the first array to the second.
The "mapping" array simply prepends a 1
or 2
to each element of the $data
array to affect the sort order moving the items not found in the $check
into first sort position.
Try it here: https://onlinephp.io/c/5ae10
CodePudding user response:
Try this. Firstly get all the items in the first array which aren't in the second array:
$data = array_diff($data, $check);
Sort both arrays:
usort($data,function($a,$b){
return $a <=> $b;
});
usort($check,function($a,$b){
return $a <=> $b;
});
Merge them together
$merged = array_merge($data, $check);
CodePudding user response:
The most modern approach is to use array_map()
with arrow syntax and check if each data value is in the check array. When sorting booleans ascending, false comes before true.
array_multisort()
is a better choice versus usort()
in this case because fewer in_array()
call will be made.
Code: (Demo)
array_multisort(
array_map(fn($v) => in_array($v, $check), $data),
$data
);
var_export($data);