Sorting a php array of arrays by custom order
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.
PHP sort multidimensional array with custom order
Your usort
is not working because $a
and $b
in the callback function are not quite what you think they are. They aren't 'term_id'
values. They are the entire inner array, e.g.
array('term_id' => 76, 'content' => 'ratio')
So using them as an argument to array_search
with your $order
array won't work, because they aren't in that array. All the array_search
es will just return false
, hence the seemingly random sort. You just need to specify the term_id
key, like this, and it will work as expected:
usort($attribute_content, function ($a, $b) use ($order) {
$pos_a = array_search($a['term_id'], $order);
$pos_b = array_search($b['term_id'], $order);
return $pos_a - $pos_b;
});
As far as the second way you tried, I'm really not sure what would be the problem. It appears to work properly: https://3v4l.org/oJhJs
Sort array of arrays by a column with custom sorting priority (not alphabetically)
Using Jonathan suggestion on using usort, you can define your custom rules for sorting in a separate function, like:
function getAnimalValue($animal) {
switch($animal) {
case 'Lion':
return 1;
case 'Dog':
return 2;
case 'Zeebra':
return 3;
case 'Cat':
return 4;
}
return 0;
}
Then, implement your own compare function:
function compare($itemA, $itemB) {
$a = getAnimalValue($itemA['animal']);
$b = getAnimalValue($itemB['animal']);
if ($a == $b) {
return 0;
}
return ($a < $b) ? -1 : 1;
}
Finally, call usort using the compare function:
usort($array, "compare");
php sort multidimentional array by custom order
Take the standard code for sorting an array by id
:
usort($data, function($x, $y) { return $x['id'] - $y['id']; });
What you want to do is sort not by the ids themselves, but rather by the "weight" of each id (which represents the arbitrary order you want the ids to be put in). So make an array where keys are ids and values are the weights and use it to convert ids to weights:
// array_flip turns 0 => 112, 1 => 111, ... into 122 => 0, 111 => 1, ...
$weights = array_flip(array('112','111','132','100'));
usort($data, function($x, $y) use($weights) {
return $weights[$x['id']] - $weights[$y['id']];
});
Update: Since you also want to handle ids that do not have a specified weight you will have to further expand the above:
usort($data, function($x, $y) use($weights) {
if (!isset($weights[$x['id']], $weights[$y['id']])) {
// none of the ids have weight, so sort by bare id
return $x['id'] - $y['id'];
}
else if (!isset($weights[$x['id']])) {
// x does not have weight, put it last
return 1;
}
else if (!isset($weights[$y['id']])) {
// y does not have weight, put it last
return -1;
}
// both have weights, use them
return $weights[$x['id']] - $weights[$y['id']];
});
php - sort array by custom criteria
The idea is to add a priority as integer, and sort the array from the highest integer to the lowest using usort()
for example you have this data
<?php
$data = [];
$data[0] = new stdClass;
$data[0]->name = "name1";
$data[0]->key = 'key1';
$data[1] = new stdClass;
$data[1]->name = "name2";
$data[1]->key = 'key2';
$data[2] = new stdClass;
$data[2]->name = "name3";
$data[2]->key = 'key3';
$keys = ["key3", "key1"];
you can sort it this way
function sortByPriority($data , $keys){
$priority = array();
$i = count($keys);
foreach ($keys as $key => $value) {
$i--;
$priority[$value] = $i;
}
usort($data, function($a, $b) use($priority){
$a = isset($priority[$a->key]) ? $priority[$a->key] : -1;
$b = isset($priority[$b->key]) ? $priority[$b->key] : -1;
return $b - $a;
});
return $data;
}
var_dump(sortByPriority($data, $keys));
sample output
array (size=3)
0 =>
object(stdClass)[3]
public 'name' => string 'name3' (length=5)
public 'key' => string 'key3' (length=4)
1 =>
object(stdClass)[1]
public 'name' => string 'name1' (length=5)
public 'key' => string 'key1' (length=4)
2 =>
object(stdClass)[2]
public 'name' => string 'name2' (length=5)
public 'key' => string 'key2' (length=4)
Sort array by keys in custom order
You could use the following comparison function:
function cmp($a, $b) {
$order = Array( 'LOW' => 0, 'MEDIUM' => 1, 'HIGH' => 2 );
return $order[$a] - $order[$b];
}
Example of this code is here.
Sort array in custom order using PHP
I would use the array containing all values in the correct order, and then filter out the elements which are not in the $data array:
$sortOrder = [ 'diamond', 'platinum', 'gold', 'silver', 'bronze', 'standard', 'branding' ];
$data = [ 'platinum', 'gold', 'silver', 'bronze', 'standard', 'branding', 'diamond' ];
$result = array_filter($sortOrder, fn($value) => in_array($value, $data));
Custom sort array in PHP
Here's some rough code to get you started:
Basically, it looks at the first letter of each word in the data array, the checks its position in the $sortOrder
array. Letters that aren't in $sortOrder
get put onto the end in the order appear.
Right off the bat, this is going to break if $sortOrder
has more than 100,000 items in it. There are probably other holes too but I figure it's a decent enough example of how usort()
works.
<?php
function getSortOrder($c) {
$sortOrder = array("j","c","z","l","a");
$pos = array_search($c, $sortOrder);
return $pos !== false ? $pos : 99999;
}
function mysort($a, $b) {
if( getSortOrder($a[0]) < getSortOrder($b[0]) ) {
return -1;
}elseif( getSortOrder($a[0]) == getSortOrder($b[0]) ) {
return 0;
}else {
return 1;
}
}
$data = array(
"banana",
"apple",
"love",
"zasca",
"japanese",
"car"
);
echo '<pre>' . print_r($data,true) . '</pre>';
usort($data, "mysort");
echo '<pre>' . print_r($data,true) . '</pre>';
?>
Related Topics
Base_Url() Function Not Working in Codeigniter
Get All Permutations of a PHP Array
Warning: MySQLi_Select_Db() Expects Exactly 2 Parameters, 1 Given
How to Fix Error: Laravel.Log Could Not Be Opened
Is There Way to Use Two PHP Versions in Xampp
Performance of For VS Foreach in PHP
How to Remove "Public/Index.PHP" in the Url Generated Laravel
Json_Encode PHP Array as Json Array Not Json Object
PHP Datetime::Modify Adding and Subtracting Months
Html Element Array, Name="Something[]" or Name="Something"
How to Delete a Line from the File With PHP
PHP Constants Containing Arrays
String Comparison Using '==' Vs. 'Strcmp()'
Full Secure Image Upload Script
What's the Best Way to Get the Last Element of an Array Without Deleting It