하위 배열 값으로 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
                )
    )

답변:


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를 사용하십시오 . 문자열 인 경우 John Johnson의 솔루션 입니다.


PHP ≥7.0에서는 오버플로 / 잘림 문제를 방지하기 위해 빼기 대신 우주선 연산자<=> 를 사용합니다 .

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

1
어려운 비트 내 머리 라운드 얻을 수있다 -에 usort 내가 그것을 사용하는 기능을 제공 필요로 정말 날 helpe하지 않습니다
Sjwdavies

17
글쎄 그는 당신에게 사용할 기능을 제공했습니다. 그리고 당신은 당신이 원하는 것을 할 수있는 내장 함수가 항상있는 것은 아니라는 것을 받아 들여야 할 것입니다. 당신은 그것을 직접 작성해야합니다. 비교 함수는 두 요소의 정렬 순서를 나타내는 1, 0 또는 -1의 반환 만 필요합니다.
Tesserex

1
나는 usort를 더 자세히 들여다 보았고 실제로 꽤 멋지다. 위의 것과 간단한 비교 함수를 작성했지만 '=='를 놓쳤습니다. 도움을 주셔서 감사합니다
Sjwdavies

3
이제 클로저로도 :-usort ($ array, function ($ a, $ b) {return $ b [ "optionNumber"]-$ a [ "optionNumber"];});
Joeri

1
@ KiloumapL'artélon 결과가 < 0이면 a이전에 나타나야 하는 정렬 기능을 알려줍니다 b. 이 경우 > 0다음 b앞에 나타납니다 a.
kennytm

57

사용하다 usort

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

7
@BenSinclair, Kenny의 솔루션은 숫자 용이므로이 솔루션은 문자열 용입니다. 둘 다 정확합니다 :-)이 대안에 대해 +1.
kubilay

대소 문자를 구분하지 않는 정렬의 경우 strcmp 대신 strcasecmp를 사용하십시오
user570605

배열에서 두 번째 순서에 대한 키를 정의 할 수 있다는 것은 먼저 optionNumber로 정렬 한 다음 lastUpdated로 정렬하는 것을 의미합니다. 이 일을 어떻게 할 수 있습니까?
Bhavin Thummar

16

나는에 의해 두 솔루션 사용 KennyTMAJ 빠른을 과 같은 많은 경우에이 문제에 도움을 줄 수있는 기능을 함께했다 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;
}

이 여기에 최고의 가장 유용한 답변이 상단에 있어야입니다)
에디 Budimilic

@EdiBudimilic 감사합니다, 감사합니다! 그런데 나는 내 대답을 업데이 트했습니다과 :이 기능의 짧은 버전 추가
Pigalev 파벨를

1
이 작업을 수행하려면 문자열을 비교할 때 와 값을 비교할 때 (마이너스) >대신 (보다 큼) 을 사용해야했습니다 . 그래도 작동합니다. -$a$b
James

1
@ 제임스 당신이 맞아요. 대답을 변경하고 우주선 연산자 (<=>) 사용을 추가했습니다. 이제 잘 작동합니다.
Pigalev Pavel

이 대소 문자를 구분하지 않는 방법이 있습니까?
loeffel 2011

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를 사용하십시오.

코드 크레딧 : http://www.firsttube.com/read/sorting-a-multi-dimensional-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

3

PHP 5.3 이상

usort($array, function($a,$b){ return $a['optionNumber']-$b['optionNumber'];} );
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.