다차원 배열을 값으로 정렬하는 방법?


1129

"order"키의 값으로이 배열을 어떻게 정렬 할 수 있습니까? 값이 현재 순차적이지만 항상 그렇지는 않습니다.

Array
(
    [0] => Array
        (
            [hashtag] => a7e87329b5eab8578f4f1098a152d6f4
            [title] => Flower
            [order] => 3
        )

    [1] => Array
        (
            [hashtag] => b24ce0cd392a5b0b8dedc66c25213594
            [title] => Free
            [order] => 2
        )

    [2] => Array
        (
            [hashtag] => e7d31fc0602fb2ede144d18cdffd816b
            [title] => Ready
            [order] => 1
        )
)


가장 빠른 방법은 브라우저와 노드 모두에서 기본적으로 작동하는 모든 유형의 입력, 계산 필드 및 사용자 정의 정렬 순서를 지원 하는 동형 정렬 배열 모듈 을 사용하는 것 입니다.
Lloyd

답변:


1732

usort을 사용해보십시오. 아직 PHP 5.2 또는 이전 버전을 사용하고 있다면 먼저 정렬 기능을 정의해야합니다.

function sortByOrder($a, $b) {
    return $a['order'] - $b['order'];
}

usort($myArray, 'sortByOrder');

PHP 5.3부터는 익명 함수를 사용할 수 있습니다 :

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

마지막으로 PHP 7에서는 우주선 연산자를 사용할 수 있습니다 .

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

이를 다차원 정렬로 확장하려면 첫 번째가 0 인 경우 두 번째 / 세 번째 정렬 요소를 참조하십시오. 아래에서 가장 잘 설명합니다. 하위 요소를 정렬하는 데 사용할 수도 있습니다.

usort($myArray, function($a, $b) {
    $retval = $a['order'] <=> $b['order'];
    if ($retval == 0) {
        $retval = $a['suborder'] <=> $b['suborder'];
        if ($retval == 0) {
            $retval = $a['details']['subsuborder'] <=> $b['details']['subsuborder'];
        }
    }
    return $retval;
});

키 연결을 유지해야하는 경우 사용 uasort()- 설명서 의 배열 정렬 기능 비교를 참조하십시오.


2
문구가 조금 벗어났습니다. 편집하겠습니다. 내가 의미하는 것은 PHP 5.3을 사용하지 않는다면이 특정 정렬을 위해 특별한 기능을 만들어야한다는 것입니다 (어쨌든 우아하지는 않습니다). 그렇지 않으면 바로 익명 함수를 사용할 수 있습니다.
Christian Studer

23
@Jonathan : PHP가하는 대부분의 작업을 실제로 볼 수는 없습니다. 배열을 가져 와서이 사용자 정의 함수에 전달 된 두 요소로 시작합니다. 그러면 함수가이를 비교할 책임이 있습니다. 첫 번째 요소가 두 번째 요소보다 큰 경우 양의 정수를 리턴하고, 작 으면 음수를 리턴하십시오. equel 인 경우 0을 반환합니다. PHP는 배열에 정렬 될 때까지 다른 두 개의 요소를 함수에 보내고 계속 그렇게합니다. 이 함수는 매우 짧으며 정수를 비교하지 않으면 훨씬 복잡 할 수 있습니다.
Christian Studer 2019

61
팁 : uasort()배열 키를 유지하려면 사용하십시오.
thaddeusmt

15
정렬 가능한 값이 10 진수 인 경우주의하십시오. 정렬 함수가 $ a = 1 및 $ b = 0.1이면 차이는 0.9이지만이 함수는 int를 반환합니다 (이 경우 0). $ a와 $ b는 동일하게 간주되어 잘못 정렬됩니다. $ a가 $ b보다 크거나 같은지 비교하고 그에 따라 -1, 1 또는 0을 반환하는 것이 더 안정적입니다.
Greenlandi

37
알아내는 데 시간이 걸렸습니다. 역순 (DESC)을 정렬하려면 $ a와 $ b를 전환하면됩니다. 따라서 $ b [ 'order']-$ a [ 'order']
JanWillem

285
function aasort (&$array, $key) {
    $sorter=array();
    $ret=array();
    reset($array);
    foreach ($array as $ii => $va) {
        $sorter[$ii]=$va[$key];
    }
    asort($sorter);
    foreach ($sorter as $ii => $va) {
        $ret[$ii]=$array[$ii];
    }
    $array=$ret;
}

aasort($your_array,"order");

7
@ noc2spam 도와 드리게되어 기쁘지만 , 더 효율적이고 깔끔한 스 터터의 제안 을 따르는 것이 좋습니다 !
o0 '.

1
@Lohoris 확실히 친구도 확인하고 있습니다. 내가이 질문을 찾지 못하면 어제는 사무실에서 더 힘든 날이었을 것입니다 :-)
Gogol

흠 대답을 추가 할 수 없습니다. 글쎄, 나는 여기에 그것을 어리석은 점이 필요하지 않습니다. , $ key1, $ key2, $ key3) {$ sorter = array (); $ ret = array (); 리셋 ($ 배열); foreach ($ array as $ ii => $ va) {$ sorter [$ ii] = getPrice ($ va [$ key1] [$ key2] [$ key3]); } arsort ($ 소터); foreach ($ sorter as $ ii => $ va) {$ ret [$ ii] = $ array [$ ii]; } $ array = $ ret; }
Jaxx0rr

3
위의 답변보다 훨씬 쉽게 신청
Marcel

1
당신은 굉장합니다! PHP 7.2에 대한 작품처럼 작동합니다.
대단히

270

이 기능을 사용합니다.

function array_sort_by_column(&$arr, $col, $dir = SORT_ASC) {
    $sort_col = array();
    foreach ($arr as $key=> $row) {
        $sort_col[$key] = $row[$col];
    }

    array_multisort($sort_col, $dir, $arr);
}


array_sort_by_column($array, 'order');

3
잘 작동합니다. 고유 한 솔루션은 정렬 방향을 추가 할 수 있습니다. 감사!
Ivo Pereira 10

2
정렬 방향과 많은 추가 기능을 지원하는 대안의 경우 여기 에서 내 대답을 살펴보고 싶을 수도 있습니다. 또한 사용 array_multisort하지 않아 사전 할당 할 필요가 없으므로 $sort_col시간과 메모리를 절약 할 수 있다는 이점이 있습니다. .
Jon

나를 위해 잘 작동하지만 ... 왜 &$arr대신 대신 지정해야 $arr합니까?
Radu Murzea

2
@RaduMurzea는 배열을 참조로 전달하고 복사본을받는 함수가 아니라 함수에 의해 수정 될 수 있습니다.
Tom Haigh

1
@AdrianP. : 배열은 참조로 전달되므로 정렬 된 사본을 반환하지 않고 전달 된 배열을 수정합니다.
Tom Haigh

72

나는 보통 usort를 사용 하고 내 자신의 비교 함수를 전달합니다. 이 경우 매우 간단합니다.

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

우주선 연산자를 사용하는 PHP 7에서 :

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

4
젠장, 나는 30 초 느렸다. 그래도 $ a-$ b 아닌가요?
Christian Studer

3
나는 항상 이것을 잘못 알고 있습니다. 매뉴얼에서 생각해 보자. 첫 번째 인수가 두 번째보다 작은 것으로 간주되면 반환 값은 0보다 작아야합니다. 따라서 $a['order']3이고 $b['order']6이면 -3을 반환합니다. 옳은?
Jan Fabry

3
글쎄, 당신은 b-a를 반환하므로 3이 될 것입니다.
Christian Studer

26
아 확인. 나는 비논리적 인 산술을 사용하고 있었는데, 당신의 머리 속에있는 아이디어는 당신이 만드는 단어와 일치하지 않습니다. 금요일 오후에 가장 자주 공부합니다.
Jan Fabry

대답은 위의 몇 가지 경우에 반환 잘못된 결과입니다 .. 참조 stackoverflow.com/questions/50636981/...
비랄 아메드

45

이것을 달성하는 한 가지 접근법은 다음과 같습니다.

    $new = [
              [
                'hashtag' => 'a7e87329b5eab8578f4f1098a152d6f4',
                'title' => 'Flower',
                'order' => 3,
              ],

              [
                'hashtag' => 'b24ce0cd392a5b0b8dedc66c25213594',
                'title' => 'Free',
                'order' => 2,
              ],

              [
                'hashtag' => 'e7d31fc0602fb2ede144d18cdffd816b',
                'title' => 'Ready',
                'order' => 1,
              ],
    ];

    $keys = array_column($new, 'order');

    array_multisort($keys, SORT_ASC, $new);

    var_dump($new);

결과:

    Array
    (
        [0] => Array
            (
                [hashtag] => e7d31fc0602fb2ede144d18cdffd816b
                [title] => Ready
                [order] => 1
            )

        [1] => Array
            (
                [hashtag] => b24ce0cd392a5b0b8dedc66c25213594
                [title] => Free
                [order] => 2
            )

        [2] => Array
            (
                [hashtag] => a7e87329b5eab8578f4f1098a152d6f4
                [title] => Flower
                [order] => 3
            )

    )

18

"title"키 값으로 배열을 정렬하려면 다음을 사용하십시오.

uasort($myArray, function($a, $b) {
    return strcmp($a['title'], $b['title']);
});

strcmp 는 문자열을 비교합니다.

uasort () 는 배열 키가 정의 된대로 유지 관리합니다.


strcmp는 varchar 유형에 대한
유용한 도움말

17
$sort = array();
$array_lowercase = array_map('strtolower', $array_to_be_sorted);
array_multisort($array_lowercase, SORT_ASC, SORT_STRING, $alphabetically_ordered_array);

대문자와 소문자 알파벳을 모두 처리합니다.


4
이것은 특정 배열 키로 정렬하는 문제에 어떻게 대답합니까?
Seano

12

사용 array_multisort(),array_map()

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

print_r($array);

데모


이 접근 방식은 알림을 표시합니다. array_multisort첫 번째 매개 변수입니다.
Kami Yang

5

가장 유연한 방법은이 방법을 사용하는 것입니다

Arr::sortByKeys(array $array, $keys, bool $assoc = true): array

이유는 다음과 같습니다.

  • 당신은 어떤 키로 정렬 할 수 있습니다 ( 'key1.key2.key3'또는 같은 중첩 ['k1', 'k2', 'k3'])

  • 연관 배열과 비 연관 배열 모두에서 작동 ( $assoc플래그)

  • 참조를 사용하지 않습니다-새로운 정렬 된 배열을 반환

귀하의 경우 다음과 같이 간단합니다.

$sortedArray = Arr::sortByKeys($array, 'order');

이 방법은 이 라이브러리 의 일부입니다 .


1

php는 모든 배열 정렬 시나리오를 올바르게 처리하는 간단한 기본 기능이 없습니다.

이 루틴은 직관적이므로 더 빠른 디버깅 및 유지 관리를 의미합니다.

// automatic population of array
$tempArray = array();
$annotations = array();
// ... some code
// SQL $sql retrieves result array $result 
// $row[0] is the ID, but is populated out of order (comes from 
// multiple selects populating various dimensions for the same DATE 
// for example
while($row = mysql_fetch_array($result)) {
    $needle = $row[0];
    arrayIndexes($needle);  // create a parallel array with IDs only
    $annotations[$needle]['someDimension'] = $row[1]; // whatever
}
asort($tempArray);
foreach ($tempArray as $arrayKey) {
    $dataInOrder = $annotations[$arrayKey]['someDimension']; 
    // .... more code
}

function arrayIndexes ($needle) {
    global $tempArray;
    if (!in_array($needle,$tempArray)) {
        array_push($tempArray,$needle);
    }
}

4
"얼굴을 보자 : PHP는 모든 배열 정렬 시나리오를 올바르게 처리 할 수있는 간단한 기능을 가지고 있지 않다." 바로 usort / ksort / asort가 ^^ '을 위해 설계된 것입니다.
Ben Cassinat

3
실제로 PHP 에는 모든 배열 정렬 시나리오를 처리하는 데 사용할 수있는 정렬 기능많이 있습니다.
axiac

디버깅 및 유지 관리와 관련하여 사용은 global막대한 위험 신호 이며 일반적으로 권장되지 않습니다 . mysql_fetch_arrayOP의 소스 배열 대신이 질문에 대해 왜 설명되고 코드에서 수행중인 작업에 대한 설명이 없으며 결과를 기대할 수있는 이유는 무엇입니까? 전반적으로 이것은 원하는 최종 결과를 얻는 데 매우 복잡한 접근 방식입니다.
fyrye가

@tonygil 나는 귀하의 답변과 OP의 데이터 세트에서 예상되는 결과가 무엇인지 결정할 수 없습니다. 당신에게 분명 할 수도 있지만, 귀하의 답변이 OP의 질문에 어떻게 대답하는지 모르겠습니다. 그러나 다음 을 사용하는 대신 참조로 전달할 수 있습니다 global. 3v4l.org/FEeFC 전역 적으로 변경하고 액세스 할 수있는 변수가 아니라 명시 적으로 정의 된 변수를 생성합니다.
fyrye

0

다음과 같이 여러 값에 대해 다차원 배열을 정렬 할 수도 있습니다.

$arr = [
    [
        "name"=> "Sally",
        "nick_name"=> "sal",
        "availability"=> "0",
        "is_fav"=> "0"
    ],
    [
        "name"=> "David",
        "nick_name"=> "dav07",
        "availability"=> "0",
        "is_fav"=> "1"
    ],
    [
        "name"=> "Zen",
        "nick_name"=> "zen",
        "availability"=> "1",
        "is_fav"=> "0"
    ],
    [
        "name"=> "Jackson",
        "nick_name"=> "jack",
        "availability"=> "1",
        "is_fav"=> "1"
    ],
    [
        "name"=> "Rohit",
        "nick_name"=> "rod",
        "availability"=> "0",
        "is_fav"=> "0"
    ],

];

usort($arr,function($a,$b){
    $c = $b['is_fav'] - $a['is_fav'];
    $c .= $b['availability'] - $a['availability'];
    $c .= strcmp($a['nick_name'],$b['nick_name']);
    return $c;
});

를 사용하여 출력 print_r($arr):

Array
(
    [0] => Array
        (
            [name] => Jackson
            [nick_name] => jack
            [availability] => 1
            [is_fav] => 1
        )

    [1] => Array
        (
            [name] => David
            [nick_name] => dav07
            [availability] => 0
            [is_fav] => 1
        )

    [2] => Array
        (
            [name] => Zen
            [nick_name] => zen
            [availability] => 1
            [is_fav] => 0
        )

    [3] => Array
        (
            [name] => Rohit
            [nick_name] => rod
            [availability] => 0
            [is_fav] => 0
        )

    [4] => Array
        (
            [name] => Sally
            [nick_name] => sal
            [availability] => 0
            [is_fav] => 0
        )

)

PS) strcmp 를 사용하면 문자열을 비교하는 것이 좋습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.