I have an array like this:
$sort_me = array(
array("file"=>"Desert.jpg"),
array("file"=>"Hello.jpg"),
array("file"=>"Test.jpg)
)
I want to sort this array based on the file attribute alphabetically. To complicate matters I have an optional array:
$sort_order = array("Test.jpg", "Hello.jpg", "NotFound.jpg")
This array will specify some user defined ordering. These array elements have priority, and will be placed in that order if they are found. Other elements not matching anything in $sort_order
should be ordered at the end of the array alphabetically.
In javascript I would use call a sort function with a comparator function that takes 2 elements and returns a number to place the first object ahead or behind the second.
How can I do this with PHP?
Edit
I attempted something and it didn't work. (Modified again to put the logic into one function, and generalize which field to sort by)
<?php
function sort_priority($sort_me, $sort_order, $field) {
function compare($a, $b) {
if ($sort_order) {
$ai = array_search($a[$field], $sort_order);
$bi = array_search($b[$field], $sort_order);
if ($ai !== false && $bi === false) {
return -1;
} else if ($bi !== false && $ai === false) {
return 1;
} else if ($ai !== false && $bi !== false) {
return $bi - $ai;
}
}
return $a[$field] < $b[$field] ? -1 : 1;
}
usort($sort_me, "compare");
}
$sort_order = array("Test.jpg", "Hello.jpg", "NotFound.jpg");
$sort_me = array(
array("file"=>"Test.jpg"),
array("file"=>"Desert.jpg"),
array("file"=>"Hello.jpg")
);
sort_priority($sort_me, $sort_order, "file");
echo json_encode($sort_me);
?>
This outputs
Notice: Undefined variable: sort_order in c:\workspace\test.php on line 10
The expected output is
[{"file":"Test.jpg"},{"file":"Hello.jpg"},{"file":"Desert.jpg"}]
I don't know how to get the compare
function to properly use the context specific $sort_order
function.
Edit
I accepted an answer, but for completeness I wanted to post what I finally ended up with that seemed to work. If anyone wants to post a more elegant solution, I would consider marking it as accepted. But here is what I have:
<?php
function compare_priority($a, $b) {
global $g_order, $g_field;
if ($g_order) {
$ai = array_search($a[$g_field], $g_order);
$bi = array_search($b[$g_field], $g_order);
if ($ai !== false && $bi === false) {
return -1;
} else if ($bi !== false && $ai === false) {
return 1;
} else if ($ai !== false && $bi !== false) {
return $ai - $bi;
}
}
return $a[$g_field] < $b[$g_field] ? -1 : 1;
}
function sort_priority(&$sort_me, $sort_order, $field) {
global $g_order, $g_field;
$g_order = $sort_order;
$g_field = $field;
usort($sort_me, "compare_priority");
}
$sort_me = array(
array("file"=>"Z"),
array("file"=>"A"),
array("file"=>"Y"),
array("file"=>"B")
);
$sort_order = array("Z", "Y", "C");
sort_priority($sort_me, $sort_order, "file");
echo json_encode($sort_me);
?>