问题
How do I sort a multidimensional array by a value, but with a custom order?
The multidimensional array will be something like:
$attribute_content[0]['term_id'] = 76;
$attribute_content[0]['content'] = "ratio";
$attribute_content[1]['term_id'] = 18;
$attribute_content[1]['content'] = "ideal condition";
$attribute_content[2]['term_id'] = 164;
$attribute_content[2]['content'] = "genotype";
$attribute_content[3]['term_id'] = 218;
$attribute_content[3]['content'] = "genetics";
$attribute_content[4]['term_id'] = 60;
$attribute_content[4]['content'] = "height";
and the ordering is according to the term_id, but will be:
$order = array(18,164,218,60,76);
I've tried the following codes which re-order the array, but seemingly randomly:
usort($attribute_content, function ($a, $b) use ($order) {
$pos_a = array_search($a, $order);
$pos_b = array_search($b, $order);
return $pos_a - $pos_b;
});
and
$weights = array_flip($order);
usort($attribute_content, function($x, $y) use($weights) {
return $weights[$x['term_id']] - $weights[$y['term_id']];
});
Please help
回答1:
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
回答2:
Yet another approach, just add the order to the array and use that to sort:
$order = array(18, 164, 218, 60, 76);
foreach ($attribute_content as $key => $values) {
$attribute_content[$key]['order'] = array_search($values['term_id'], $order);
}
usort($attribute_content, function($a, $b) {
return $a['order'] > $b['order'];
});
回答3:
This is what I'd do:
$sortedArray = array();
for ($count = 0; $count < count($order); $count++) {
for ($i = 0; $i < count($attribute_content); $i++) {
if ($order[$count] == $attribute_content[$i]["term_id"]) {
$sortedArray[count($sortedArray)] = $attribute_content[$i];
}
}
}
$attribute_content = $sortedArray;
It'll cycle through the array and put the values into a new, sorted array in the order provided. Afterwards, it will set the pre-existing array to the sorted array, however you can remove that line if you don't mind using $sortedArray, or if you just want to rename it and use it.
回答4:
Here's another approach using array_multisort():
<?php
$order = array(18,164,218,60,76);
$attribute_content = array(
array('term_id' => 76, 'content' => 'ratio'),
array('term_id' => 18, 'content' => 'ideal condition'),
array('term_id' => 164,'content' => 'genotype'),
array('term_id' => 218,'content' => 'genetics'),
array('term_id' => 60, 'content' => 'height')
);
foreach($attribute_content as $k=>$r){
$term_id = $r['term_id'];
$custom_order = 0;
if( in_array($term_id,$order) ){
$custom_order = array_search($term_id,$order);
}
$tmp[] = $custom_order;
}
array_multisort($tmp,SORT_ASC,$attribute_content);
echo '<pre>',print_r($attribute_content),'</pre>';
来源:https://stackoverflow.com/questions/38445956/php-sort-multidimensional-array-with-custom-order