Search code examples
phparrayssortingmultidimensional-arrayarray-multisort

Sort columns in an associative array of indexed arrays by multiple criteria


Given the following array:

$array = array(
    'note' => array('test', 'test1', 'test2', 'test3', 'test4'),
    'year' => array('2011','2010', '2012', '2009', '2010'),
    'type' => array('journal', 'conference', 'editorial', 'conference','conference'),
);

Array can be easily transposed if it is easier (using the following function):

for ($i = 0; $i < count($array['type']); $i++)
  foreach ($array as $key => $value)
    $temp[$i][$key] = $value[$i];

print_r($temp);

And I want to sort it using the following criteria:

  1. An array $sortby = ('journal', 'editorial', 'conference')
  2. After sorting in categories I would like to sort by year DESC for every category.

Desired result:

Array
(
[note] => Array
    (
        [0] => test
        [1] => test2
        [2] => test1
        [3] => test4
        [4] => test3
    )

[year] => Array
    (
        [0] => 2011
        [1] => 2012
        [2] => 2010
        [3] => 2010
        [4] => 2009
    )

[type] => Array
    (
        [0] => journal
        [1] => editorial
        [2] => conference
        [3] => conference
        [4] => conference
    )

)

Solution

  • If you transpose your input array, then you'll be able to sort by column at a time.

    $Array = array(
        array('note' => 'test1', 'year' => '2011', 'type' => 'journal'),
        array('note' => 'test2', 'year' => '2012', 'type' => 'editorial'),
        array('note' => 'test3', 'year' => '2012', 'type' => 'conference'),
        array('note' => 'test4', 'year' => '2012', 'type' => 'conference'),
        array('note' => 'test5', 'year' => '2012', 'type' => 'conference')
    );
    

    Let's sort them by year value.

    function array_sort_by_column(&$arr, $col, $dir = SORT_DESC) {
        $sort_col = array();
        foreach ($arr as $key=> $row) {
            $sort_col[$key] = $row[$col];
        }
        return array_multisort($sort_col, $dir, $arr);
    }
    
    array_sort_by_column($Array, 'year');
    print_r($Array);
    

    Output:

    Array
    (
        [0] => Array
            (
                [note] => test2
                [year] => 2012
                [type] => editorial
            )
    
        [1] => Array
            (
                [note] => test3
                [year] => 2012
                [type] => conference
            )
    
        [2] => Array
            (
                [note] => test4
                [year] => 2012
                [type] => conference
            )
    
        [3] => Array
            (
                [note] => test5
                [year] => 2012
                [type] => conference
            )
    
        [4] => Array
            (
                [note] => test1
                [year] => 2011
                [type] => journal
            )
    
    )
    

    Sort them by note value.

    array_sort_by_column($Array, 'note');
    print_r($Array);
    

    Output:

    Array
    (
        [0] => Array
            (
                [note] => test5
                [year] => 2012
                [type] => conference
            )
    
        [1] => Array
            (
                [note] => test4
                [year] => 2012
                [type] => conference
            )
    
        [2] => Array
            (
                [note] => test3
                [year] => 2012
                [type] => conference
            )
    
        [3] => Array
            (
                [note] => test2
                [year] => 2012
                [type] => editorial
            )
    
        [4] => Array
            (
                [note] => test1
                [year] => 2011
                [type] => journal
            )
    
    )
    

    Sort by type value.

    array_sort_by_column($Array, 'type');
    print_r($Array);
    

    Output:

    Array
    (
        [0] => Array
            (
                [note] => test1
                [year] => 2011
                [type] => journal
            )
    
        [1] => Array
            (
                [note] => test2
                [year] => 2012
                [type] => editorial
            )
    
        [2] => Array
            (
                [note] => test3
                [year] => 2012
                [type] => conference
            )
    
        [3] => Array
            (
                [note] => test4
                [year] => 2012
                [type] => conference
            )
    
        [4] => Array
            (
                [note] => test5
                [year] => 2012
                [type] => conference
            )
    
    )