按子数组值排序数组

我有以下数组结构:

Array
(
[0] => Array
(
[configuration_id] => 10
[id] => 1
[optionNumber] => 3
[optionActive] => 1
[lastUpdated] => 2010-03-17 15:44:12
)


[1] => Array
(
[configuration_id] => 9
[id] => 1
[optionNumber] => 2
[optionActive] => 1
[lastUpdated] => 2010-03-17 15:44:12
)


[2] => Array
(
[configuration_id] => 8
[id] => 1
[optionNumber] => 1
[optionActive] => 1
[lastUpdated] => 2010-03-17 15:44:12
)
)

基于 optionNumber以增量方式对数组进行排序的最佳方法是什么?

结果是这样的:

Array
(
[0] => Array
(
[configuration_id] => 8
[id] => 1
[optionNumber] => 1
[optionActive] => 1
[lastUpdated] => 2010-03-17 15:44:12
)


[1] => Array
(
[configuration_id] => 9
[id] => 1
[optionNumber] => 2
[optionActive] => 1
[lastUpdated] => 2010-03-17 15:44:12
)


[2] => Array
(
[configuration_id] => 10
[id] => 1
[optionNumber] => 3
[optionActive] => 1
[lastUpdated] => 2010-03-17 15:44:12
)
)
86339 次浏览

使用 usort

function cmp_by_optionNumber($a, $b) {
return $a["optionNumber"] - $b["optionNumber"];
}


...


usort($array, "cmp_by_optionNumber");

在 PHP ≥5.3时,应该使用 匿名函数:

usort($array, function ($a, $b) {
return $a['optionNumber'] - $b['optionNumber'];
});

注意,上面两段代码都假设 $a['optionNumber']是一个整数。如果它们是字符串,则使用 @ St. John Johnson’s Solution


在 PHP ≥7.0时,使用 宇宙飞船操作员 <=>代替减法,以防止溢出/截断问题。

usort($array, function ($a, $b) {
return $a['optionNumber'] <=> $b['optionNumber'];
});

使用 usort

 usort($array, 'sortByOption');
function sortByOption($a, $b) {
return strcmp($a['optionNumber'], $b['optionNumber']);
}

当使用类似上面的函数时,键被删除。如果键很重要,下面的函数会维护它... ... 但 foreach 循环的效率非常低。

function subval_sort($a,$subkey) {
foreach($a as $k=>$v) {
$b[$k] = strtolower($v[$subkey]);
}
asort($b);
foreach($b as $key=>$val) {
$c[$key] = $a[$key];
}
return $c;
}
$array = subval_sort($array,'optionNumber');

如果要从高到低排序,请使用 arsort 而不是 assort。

密码: http://www.firsttube.com/read/sorting-a-multi-dimensional-array-with-php/

PHP 5.3 +

usort($array, function($a,$b){ return $a['optionNumber']-$b['optionNumber'];} );

我使用了 KennyAJ 奎克的两种解决方案,并提出了一个函数,可以帮助在这个问题的许多情况下,如 使用 ASC 或 DESC排序或 保存钥匙或如果你有 对象作为数组的子对象

下面是这个函数(适用于 PHP7或更高版本,因为有了飞船操作员) :

/**
* @param array $array
* @param string $value
* @param bool $asc - ASC (true) or DESC (false) sorting
* @param bool $preserveKeys
* @return array
* */
function sortBySubValue($array, $value, $asc = true, $preserveKeys = false)
{
if ($preserveKeys) {
$c = [];
if (is_object(reset($array))) {
foreach ($array as $k => $v) {
$b[$k] = strtolower($v->$value);
}
} else {
foreach ($array as $k => $v) {
$b[$k] = strtolower($v[$value]);
}
}
$asc ? asort($b) : arsort($b);
foreach ($b as $k => $v) {
$c[$k] = $array[$k];
}
$array = $c;
} else {
if (is_object(reset($array))) {
usort($array, function ($a, $b) use ($value, $asc) {
return $a->{$value} == $b->{$value} ? 0 : ($a->{$value} <=> $b->{$value}) * ($asc ? 1 : -1);
});
} else {
usort($array, function ($a, $b) use ($value, $asc) {
return $a[$value] == $b[$value] ? 0 : ($a[$value] <=> $b[$value]) * ($asc ? 1 : -1);
});
}
}


return $array;
}

用法:

sortBySubValue($array, 'optionNumber', true, false);

剪辑

第一部分可以重写使用 uasort()和函数将更短(工程为 PHP7和更高,因为宇宙飞船操作员) :

/**
* @param array $array
* @param string $value
* @param bool $asc - ASC (true) or DESC (false) sorting
* @param bool $preserveKeys
* @return array
* */
function sortBySubValue($array, $value, $asc = true, $preserveKeys = false)
{
if (is_object(reset($array))) {
$preserveKeys ? uasort($array, function ($a, $b) use ($value, $asc) {
return $a->{$value} == $b->{$value} ? 0 : ($a->{$value} <=> $b->{$value}) * ($asc ? 1 : -1);
}) : usort($array, function ($a, $b) use ($value, $asc) {
return $a->{$value} == $b->{$value} ? 0 : ($a->{$value} <=> $b->{$value}) * ($asc ? 1 : -1);
});
} else {
$preserveKeys ? uasort($array, function ($a, $b) use ($value, $asc) {
return $a[$value] == $b[$value] ? 0 : ($a[$value] <=> $b[$value]) * ($asc ? 1 : -1);
}) : usort($array, function ($a, $b) use ($value, $asc) {
return $a[$value] == $b[$value] ? 0 : ($a[$value] <=> $b[$value]) * ($asc ? 1 : -1);
});
}
return $array;
}

使用 array _ multisort ()、 array _ map ()

array_multisort(array_map(function($element) {
return $element['optionNumber'];
}, $array), SORT_ASC, $array);


print_r($array);

演示

使用 array_multisortarray_column的一行式解决方案。

//your array
$yourarray = Array
(
"0" => Array
(
"configuration_id" => 10,
"id" => 1,
"optionNumber" => 3,
"optionActive" => 1,
"lastUpdated" => "2010-03-17 15:44:12"
),
"1" => Array
(
"configuration_id" => 9,
"id" => 1,
"optionNumber" => 2,
"optionActive" => 1,
"lastUpdated" => "2010-03-17 15:44:12"
),
"2" => Array
(
"configuration_id" => 8,
"id" => 1,
"optionNumber" => 1,
"optionActive" => 1,
"lastUpdated" => "2010-03-17 15:44:12"
)
);


//access optionNumber in the child arrays using array_column
array_multisort(array_column($yourarray, 'optionNumber'), SORT_ASC, $yourarray);


//print out preformatted
echo "<pre>"; print_r($images); echo "</pre>";

最现代、最简洁的两种方法是:

  1. 带有箭头函数语法和一个宇宙飞船(3路比较)操作符的 usort()

    usort($array, fn($a, $b) =>
    $a['optionNumber'] <=> $b['optionNumber']
    );
    

    $a <=> $b提供升序排序; $b <=> $a提供降序排序。

  2. 使用 array_column()调用来隔离要比较的值

    array_multisort(
    array_column($array, 'optionNumber'),
    $array
    );
    

    没有必要包含排序方向标志,因为如果省略,升序是默认/隐含的方向。


上述两种方法都要求目标数组列存在于所有行中,否则方法将失败/中断/错误。