简体   繁体   中英

Alphabetically sort multidimensional array's keys and values recursively in PHP

I need help sorting keys and values of the array below alphabetically:

$unsorted = [
    'D' => [
        'C' => ['c', 'b', 'a'],
        'B' => 'bvalue',
        'A' => ['a', 'c', 'b'],
    ],
    'C' => 'cvalue',
    'B' => 'bvalue',
    'A' => [
        'Z' => 'zvalue',
        'A' => 'avalue',
        'B' => 'bvalue',
    ]
];

The sort has to be recursive as the array above is multidimensional. It holds other arrays (numerically indexed and associative) as its values.

I managed to sort the array's keys recursively using this function:

function sortKeysRecursive(&$array)
{
    foreach ($array as $key => &$value) {
        if (is_array($value)) {
            sortKeysRecursive($value);
        }
    }

    ksort($array);
}

However, I was unable to sort the values without messing with already sorted keys. To sort the values I tried to apply this function:

function sortValuesRecursive(&$array)
{
    foreach ($array as &$value) {
        if (is_array($value)) {
            sortValuesRecursive($value);
        }
    }
    asort($value);
}

sortKeysRecursive($unsorted);
sortValuesRecursive($unsorted);

But it's one or the other. Both function applied to the same array always mess the other functions work.

I'd expect to produce sorted array that looks like this:

$sorted = [
    'A' => [
        'A' => 'avalue',
        'B' => 'bvalue',
        'Z' => 'zvalue',
    ],
    'B' => 'bvalue',
    'C' => 'cvalue',
    'D' => [
        'A' => ['a', 'b', 'c'],
        'B' => 'bvalue',
        'C' => ['a', 'b', 'c'],
    ],
];

I'd be grateful for help.

you need to check keys are numeric or alphabetic. try below solution you may need to modify conditions for your purpose:

<?php

function isAssoc(array $arr)
{
    return array_keys($arr) !== range(0, count($arr) - 1);
}

function sortArray(&$arr){
    if(isAssoc($arr)){
        ksort($arr);
    } else{
        asort($arr);
    }
    foreach ($arr as &$a){
        if(is_array($a)){
            sortArray($a);
        }
    }
}

$unsorted = array(
    'D' => array(
        'C' => array('c', 'b', 'a'),
        'B' => 'bvalue',
        'A' => array('a', 'c', 'b'),
    ),
    'C' => 'cvalue',
    'B' => 'bvalue',
    'A' => array(
        'Z' => 'zvalue',
        'A' => 'avalue',
        'B' => 'bvalue',
    )
);
sortArray($unsorted);

print_r($unsorted);

Output

Array
(
    [A] => Array
        (
            [A] => avalue
            [B] => bvalue
            [Z] => zvalue
        )

    [B] => bvalue
    [C] => cvalue
    [D] => Array
        (
            [A] => Array
                (
                    [0] => a
                    [2] => b
                    [1] => c
                )

            [B] => bvalue
            [C] => Array
                (
                    [2] => a
                    [1] => b
                    [0] => c
                )

        )

)

Use following method and loop through the $unsorted array and sort conditionally:

function recursiveSort(array &$unsorted) {

    // Sort array keys
    ksort($unsorted);

    foreach ($unsorted as $key => $array) {
        if (!is_array($array)) {
            continue;
        }

        if (is_numeric(key($array))) {
            asort($array);
        } else {
            recursiveSort($array);
        }
        $unsorted[$key] = $array;
    }
}

Usage:

recursiveSort($unsorted);

Hope it helps

function sortKeysRecursive(&$array)
{
    foreach ($array as $key => &$value) {
        if (is_array($value)) {
            sortKeysRecursive($value);
        }
    }

    ksort($array);
}

/**
 * Sort only the arrays that doesn't have a child array, this way
 * we don't mess with what sortKeysRecursive has sorted
 */
function sortValuesRecursive(&$array)
{
    $isArray = false;

    foreach ($array as $key => &$value) {
        if (is_array($value)) {
            $isArray = true;
            sortValuesRecursive($value);
        }
    }

    if ($isArray === false) {
        asort($array);
    }
}

sortKeysRecursive($unsorted);
sortValuesRecursive($unsorted);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM