phparrayssortingmultidimensional-arrayalternating

Order rows by their column value to create repeating sequences of ascending values


I want to order my associative rows by their column value as sequences of ascending values.

Sample array1:

$args = [
    'a' => ['zebra' => 1],
    'b' => ['zebra' => 0],
    'c' => ['zebra' => 0],
    'd' => ['zebra' => 0],
    'e' => ['zebra' => 1],
];

Desired result:

[
    'b' => ['zebra' => 0],
    'a' => ['zebra' => 1],
    'c' => ['zebra' => 0],
    'e' => ['zebra' => 1],
    'd' => ['zebra' => 0],
]

Notice that duplicate values are not consecutive while sorting ascending. Instead, all unique, first-encountered values come first, then second encountered values, etc.

Sample array2:

$args = [
    'a' => ['zebra' => 1],
    'b' => ['zebra' => 1],
    'c' => ['zebra' => 1],
    'd' => ['zebra' => 1],
    'e' => ['zebra' => 0],
    'f' => ['zebra' => 0],
];

Desired result:

[
    'e' => ['zebra' => 0],
    'a' => ['zebra' => 1],
    'f' => ['zebra' => 0],
    'b' => ['zebra' => 1],
    'c' => ['zebra' => 1],
    'd' => ['zebra' => 1],
]

Edit: I tried to do this with usort, via this similar, but different, question, and the answer was no, so I am looking for a programatic solution (without usort).


Solution

  • Same idea to split the input into the 1's and 0's, then output a 0 and a 1 as long as there is something left to output. As each time you output a value, the array is reduced, this just continues till both lists are empty so should cope with unbalanced lists...

    $temp = [ 0 => [], 1 => []];
    
    foreach($args as $key=>$value){
        $temp[$value['zebra']][] = $key;
    }
    
    $output = [];
    while ( !empty($temp[0]) || !empty($temp[1]) )   {
        if ( !empty($temp[0]) )   {
            $next = array_shift($temp[0]);
            $output [$next] = $args[$next];
        }
        if ( !empty($temp[1]) )   {
            $next = array_shift($temp[1]);
            $output [$next] = $args[$next];
        }
    }