Reorganizing a PHP array structure (arrays within arrays)
Why

You're replacing the indexed item for the date when you declare a new array in the line:

$mainarr[$array[$i][1]] = array( $array[$i][0]=&gt; array('downloads'=&gt; 666, 'col'=&gt;$array[$i][2]) );

See it as $array[$index] = array(...) -- running it again over the same index would replace the value at that index.

Quick Fix

You could simply replace that line with (considering that there'll not be more than one line for a given country, for the same date, as in: no two DE for 2015-06-08):

if (!isset($mainarr[$array[$i][1]])) { $mainarr[$array[$i][1]] = array(); }
$mainarr[$array[$i][1]][$array[$i][0]] = array('downloads'=&gt; 666, 'col'=&gt;$array[$i][2]);


Note that $array[$i][0] (aka the country) moved to the left site of =, and the outer array on the right side of it was removed.

How would I do

I refactored the code to be more legible and easier to understand, and also use better practices IMHO:

function get_cols_to_array_by_date($array) { 
    // set the name of the variable to a more meaningful one
    $result = array();

    foreach ($array as $i =&gt; $data) {
        // shortcuts to prevent having to remember which index they are (you could change them for constants)
        $country = $data[0];
        $date = $data[1];
        $col = $data[2];

        $download = 123; // don't know where 'download' value comes from, put it here

        // you need to check if the date index already exists
        // if not, create the empty array for the date
        if (!isset($result[$date])) {
            $result[$date] = array();
        }

        // considering that country will NOT repeat for a given date
        $result[$date][$country] = array(
            'column' =&gt; $col,
            'download' =&gt; $download,
        );
    }

    return $result;
}