PHP按子数组值对数组排序


110

我有以下数组结构:

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
                )
    )

Answers:


204

使用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。约翰逊的解决方案,如果他们是字符串。


在PHP≥7.0,使用飞船运营商<=>,而不是减法,以防止溢出/截断问题。

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

1
这对我没有真正的帮助,因为usort要求我提供它要使用的功能-这是我无法理解的困难之处
Sjwdavies 2010年

17
好吧,他只是给了您要使用的功能。您将不得不接受的是,并非总是有内置函数可以执行所需的操作,您必须自己编写它。比较函数仅需要返回1、0或-1来指示两个元素的排序顺序。
Tesserex

1
我进一步研究了usort,它实际上很酷。我为上面的函数编写了一个简单的比较函数,但是错过了'=='。感谢您的帮助
Sjwdavies 2010年

3
现在也作为闭包:-usort($ array,function($ a,$ b){return $ b [“ optionNumber”]-$ a [“ optionNumber”];});
Joeri 2014年

1
@KiloumapL'artélon如果结果为< 0,则告诉排序函数a应该出现在之前b。如果是的> 0b应该出现在前面a
kennytm

57

usort

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

7
@BenSinclair,这是因为Kenny的解决方案是针对数字的,而此解决方案则是针对字符串的。他们都是正确的:-) +1对于这种选择。
kubilay

对于不区分大小写的排序,请使用strcasecmp而不是strcmp
user570605 '18

我们可以为数组中的第二个顺序定义键吗?这意味着我们首先使用optionNumber进行排序,然后使用lastUpdated进行排序。这东西怎么办?
Bhavin Thummar '19

16

我同时使用了KennyTMAJ Quick的解决方案,并提出了可以在许多情况下解决此问题的功能,例如使用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;
}

这是最好的最有用的答案,应该放在顶部;)
Edi Budimilic

@EdiBudimilic谢谢你,我很感激!顺便说一下,我已经更新了答案,并添加了该函数的较短版本:)
Pigalev Pavel 2015年

1
为了使这项工作对我有用,因为在比较字符串时,我在比较和值时必须使用>(大于)而不是-(减号)。仍然可以。$a$b
詹姆斯

1
@詹姆斯,你是对的。我更改了答案,并添加了使用宇宙飞船运算符(<=>)的功能。现在应该可以正常工作了。
Pigalev Pavel

有没有办法使这种情况不区分大小写?
loeffel

4

使用上述功能时,键会被删除。如果键很重要,则以下函数将对其进行维护...但是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而不是asort。

代码信用:http//www.firsttube.com/read/sorting-a-multi-Dimension-array-with-php/


4

使用array_multisort(),array_map()

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

print_r($array);

演示


2
这很容易工作。谢谢。我所要做的就是更改列名,该列名有效。
Kobus Myburgh,

2
这也保留键父阵列
JonnyS

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.