I have following array
Array
(
[0] => Array
(
[label] => Germany
[conversions] => 1
)
[1] => Array
(
[label] => United States
[conversions] => 8
)
[2] => Array
(
[label] => France
[conversions] => 1
)
[3] => Array
(
[label] => China
[conversions] => 1
)
[4] => Array
(
[label] => Philippines
[conversions] => 1
)
[5] => Array
(
[label] => Turkey
[conversions] => 1
)
)
I want to order following array, first by conversions (desc), then by label (asc)
output will have following sequence:
United States
China
France
Germany
Philippines
Turkey
If using >= PHP 5.3...
usort($arr, function($a, $b) {
$diff = $b['conversions'] - $a['conversions'];
if ( ! $diff) {
return strcmp($a['label'], $b['label']);
}
return $diff;
});
It is relatively simple to make it work with < PHP 5.3.
You need to use PHP's usort()
function. This allows you to write a function which determines the sort order, so you can sort things into any order you like.
The function will be called repeatedly by the usort()
algorithm, and will give you two parameters, being the two elements of the array that it wants to sort at any given moment. Your function should return -1 if the first of those two elements is bigger, +1 if it the second is bigger, and zero if they are to be considered the same for the purposes of the sort.
See the PHP manual page for more info and examples: http://php.net/manual/en/function.usort.php
I preferred array_multisort
PHP Manual in my answer below as you can specify the sort order with parameters.
Next to flexibility it should be faster than using usort
which has the problem that it's not really parametrized for the sort order, so not re-inventing the wheel as well.
For more comfort, wrap it up into a function to specify the keys as strings (Demo):
$sorted = $multisortByKey($array, 'conversions', SORT_DESC, 'label', SORT_ASC);
as in:
$array = array(
0 => array(
'label' => 'Germany',
'conversions' => 1,
),
1 => array(
'label' => 'United States',
'conversions' => 8,
),
2 => array(
'label' => 'France',
'conversions' => 1,
),
3 => array(
'label' => 'China',
'conversions' => 1,
),
4 => array(
'label' => 'Philippines',
'conversions' => 1,
),
5 => array(
'label' => 'Turkey',
'conversions' => 1,
),
);
$multisortByKey = function(array $a) {
$args = func_get_args();
$a = array_shift($args);
$extract = function($k) use($a) {return array_map(function($v) use($k) { return $v[$k]; }, $a); };
# NOTE: The following check/for-loop is not entirely correct
# as multiple sort parameters per entry are allowed. I leave this
# for practice.
$c = count($args);
if(!$c%2) throw new InvalidArgumentException('Parameter count mismatch');
for($i=0;$i<$c;$i+=2)
$args[$i] = $extract($args[$i]);
$args[] = &$a;
call_user_func_array('array_multisort', $args);
return $a;
};
$sorted = $multisortByKey($array, 'conversions', SORT_DESC, 'label', SORT_ASC);
var_dump($sorted);
try this
$myArray="your array";
<?php
foreach($myArray as $c=>$key) {
$sort_conv[$c] = $key['conversions'];
$sort_lable[$c] = $key['label'];
}
array_multisort($sort_conv, SORT_ASC, $sort_lable, SORT_STRING, $myArray);
print_r($myArray);
?>
You can use usort
to provide your own sorting function
usort($a, function($x, $y) {
return $y["conversions"] < $x["conversions"] ? 1 :
($x["conversions"] < $y["conversions"] ? -1 :
strcmp($x["label"], $y["label"]))
);
});
Try the following: (didn't test it, source: PHP Example #3)
foreach ($data as $key => $row) {
$label[$key] = $row['label'];
$conversion[$key] = $row['conversion'];
}
array_multisort($conversion, SORT_DESC, $label, SORT_ASC, $data);
精彩评论