2
\$\begingroup\$

I have this array within array which contains a lot of values:

  183 => 
    array (size=3)
      0 => string 'DE' (length=2)
      1 => string '2015-06-09' (length=10)
      2 => string 'GK' (length=2)   
  184 => 
    array (size=3)
      0 => string 'DE' (length=2)
      1 => string '2015-06-08' (length=10)
      2 => string 'GL' (length=2)   
  185 => 
    array (size=3)
      0 => string 'FR' (length=2)
      1 => string '2015-06-09' (length=10)
      2 => string 'GN' (length=2)   
  186 => 
    array (size=3)
      0 => string 'FR' (length=2)
      1 => string '2015-09-08' (length=10)
      2 => string 'GO' (length=2)

0 is the country code. 1 is a date. 2 is a column on an Excel file.

I want to organize it in this way:

2015-06-09 => 
  array (size=3)
    DE => 
      array (size=2)
        column => GK
        download => 666 
    FR => 
      array (size=2)
        column => GN
        download => 777 

2015-06-08 =>
  array (size=3)
    DE => 
      array (size=2)
        column => GL
        download => 666 
    FR => 
      array (size=2)
        column => GO
        download => 777 

So the same date can show up more than once. if it gets to an array value with the same date - it inserts in it the country code with and its' column.

if it has more than 1 country - it adds a new country. (with the 'download' and column values).

I have this function:

function get_cols_to_array_by_date($array) { 

    $mainarr = array();

    $last_in_arr = count($array); 

    for ($i=0; $i<$last_in_arr; $i++){

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


    }

    return $mainarr;


}

which outputs an array that runs over the country when it gets to the same date and doesn't give me an array of countries.

What part am I missing in my code? Is there a simpler way to do it? ( PHP syntax shortcuts ;) )

\$\endgroup\$
1
\$\begingroup\$

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]=> array('downloads'=> 666, 'col'=>$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'=> 666, 'col'=>$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 => $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' => $col,
            'download' => $download,
        );
    }

    return $result;
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.