I have an array of arrays:
Array ( [0] => Array ( [id] = 7867867, [title] = 'Some Title'), [1] => Array ( [id] = 3452342, [title] = 'Some Title'), [2] => Array ( [id] = 1231233, [title] = 'Some Title'), [3] => Array ( [id] = 5867867, [title] = 'Some Title') )
The need to go in a specific order:
How would I go about doing that? I have sorted arrays before, and read plenty of other posts about it, but they are always comparison based (i.e. valueA < valueB).
Help is appreciated.
php function sortArray() { $inputArray = array(8, 2, 7, 4, 5); $outArray = array(); for($x=1; $x<=100; $x++) { if (in_array($x, $inputArray)) { array_push($outArray, $x); } } return $outArray; } $sortArray = sortArray(); foreach ($sortArray as $value) { echo $value . "<br />"; } ?>
The arsort() function sorts an associative array in descending order, according to the value. Tip: Use the asort() function to sort an associative array in ascending order, according to the value. Tip: Use the krsort() function to sort an associative array in descending order, according to the key.
You can use usort()
to dictate precisely how the array is to be sorted. In this case, the $order
array can be used within the comparison function.
The example below uses a closure
to make life easier.
$order = array(3452342, 5867867, 7867867, 1231233); $array = array( array('id' => 7867867, 'title' => 'Some Title'), array('id' => 3452342, 'title' => 'Some Title'), array('id' => 1231233, 'title' => 'Some Title'), array('id' => 5867867, 'title' => 'Some Title'), ); usort($array, function ($a, $b) use ($order) { $pos_a = array_search($a['id'], $order); $pos_b = array_search($b['id'], $order); return $pos_a - $pos_b; }); var_dump($array);
The key to this working is having the values that are being compared, be the positions of the id
s within the $order
array.
The comparison function works by finding the positions of the ids of two items to be compared within the $order
array. If $a['id']
comes before $b['id']
in the $order
array, then the return value of the function will be negative ($a
is less so "floats" to the top). If $a['id']
comes after $b['id']
then the function returns a positive number ($a
is greater so "sinks" down).
Finally, there is no special reason for using a closure; it's just my go-to way of writing these sorts of throwaway functions quickly. It could equally use a normal, named function.
Extending salathe's answer for this additional requirement:
Now what happens when I add items to the array and not to the sort? I don't care what order they appear, as long as it comes after the ones that I did specify.
You need to add two additional conditions in the sorting function:
So the revised code would be:
$order = array( 3452342, 5867867, 7867867, 1231233 ); $array = array( array("id" => 7867867, "title" => "Must Be #3"), array("id" => 3452342, "title" => "Must Be #1"), array("id" => 1231233, "title" => "Must Be #4"), array("id" => 5867867, "title" => "Must Be #2"), array("id" => 1111111, "title" => "Dont Care #1"), array("id" => 2222222, "title" => "Dont Care #2"), array("id" => 3333333, "title" => "Dont Care #3"), array("id" => 4444444, "title" => "Dont Care #4") ); shuffle($array); // for testing var_dump($array); // before usort($array, function ($a, $b) use ($order) { $a = array_search($a["id"], $order); $b = array_search($b["id"], $order); if ($a === false && $b === false) { // both items are dont cares return 0; // a == b } else if ($a === false) { // $a is a dont care return 1; // $a > $b } else if ($b === false) { // $b is a dont care return -1; // $a < $b } else { return $a - $b; // sort $a and $b ascending } }); var_dump($array); // after
Output:
Before | After -------------------------------+------------------------------- array(8) { | array(8) { [0]=> | [0]=> array(2) { | array(2) { ["id"]=> | ["id"]=> int(4444444) | int(3452342) ["title"]=> | ["title"]=> string(12) "Dont Care #4" | string(10) "Must Be #1" } | } [1]=> | [1]=> array(2) { | array(2) { ["id"]=> | ["id"]=> int(3333333) | int(5867867) ["title"]=> | ["title"]=> string(12) "Dont Care #3" | string(10) "Must Be #2" } | } [2]=> | [2]=> array(2) { | array(2) { ["id"]=> | ["id"]=> int(1231233) | int(7867867) ["title"]=> | ["title"]=> string(10) "Must Be #4" | string(10) "Must Be #3" } | } [3]=> | [3]=> array(2) { | array(2) { ["id"]=> | ["id"]=> int(1111111) | int(1231233) ["title"]=> | ["title"]=> string(12) "Dont Care #1" | string(10) "Must Be #4" } | } [4]=> | [4]=> array(2) { | array(2) { ["id"]=> | ["id"]=> int(5867867) | int(2222222) ["title"]=> | ["title"]=> string(10) "Must Be #2" | string(12) "Dont Care #2" } | } [5]=> | [5]=> array(2) { | array(2) { ["id"]=> | ["id"]=> int(2222222) | int(1111111) ["title"]=> | ["title"]=> string(12) "Dont Care #2" | string(12) "Dont Care #1" } | } [6]=> | [6]=> array(2) { | array(2) { ["id"]=> | ["id"]=> int(3452342) | int(3333333) ["title"]=> | ["title"]=> string(10) "Must Be #1" | string(12) "Dont Care #3" } | } [7]=> | [7]=> array(2) { | array(2) { ["id"]=> | ["id"]=> int(7867867) | int(4444444) ["title"]=> | ["title"]=> string(10) "Must Be #3" | string(12) "Dont Care #4" } | } } | }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With