Skip to main content
removed tag from header
Link
Quill
  • 12.1k
  • 5
  • 41
  • 94

Extracting data from an array of arrays, PHP style

added 556 characters in body; edited tags
Source Link
Jamal
  • 35.2k
  • 13
  • 134
  • 238
Year    type01  type02  type03  type09
1995    3       0       0       2
1996    0       0       1       0
1997    0       1       0       0
1998    0       0       0       1
1999    0       1       0       0
Year    type01    type02    type03    type09
1995    3         0         0         2
1996    0         0         1         0
1997    0         1         0         0
1998    0         0         0         1
1999    0         1         0         0
$sorted = array();
$types = array();
array_walk($array1, function($v) use (&$sorted, &$types){
   if( !isset($sorted[$v[1]]) )
       $sorted[$v[1]] = array();
   $sorted[$v[1]][] = $v[0];
   $types[] = $v[0];
});

// filter types
$types = array_unique($types);
sort($types);

// sort year
ksort($sorted);

echo '----' . implode(' ,', $types) . "\r\n";
foreach($sorted as $year => $data)
{   echo $year . ' - ';
    $count = array_count_values($data);

   foreach($types as $type)
   {  
      if( !isset($count[$type]))
      {
          echo '0,';
      } else {
          echo $count[$type].',';
      }
   }
   echo "\r\n";
}
$sorted = array();
$types = array();
array_walk($array1, function($v) use (&$sorted, &$types){
   if( !isset($sorted[$v[1]]) )
       $sorted[$v[1]] = array();
   $sorted[$v[1]][] = $v[0];
   $types[] = $v[0];
});

// filter types
$types = array_unique($types);
sort($types);

// sort year
ksort($sorted);

echo '----' . implode(' ,', $types) . "\r\n";
foreach($sorted as $year => $data)
{    echo $year . ' - ';
    $count = array_count_values($data);

   foreach($types as $type)
   {  
      if( !isset($count[$type]))
      {
          echo '0,';
      } else {
          echo $count[$type].',';
      }
   }
   echo "\r\n";
}
$finalArray = array();
$years = array();

foreach ($array1 as $ix) {
    // $ix[0] is typeNN, $ix[1] is year.
    // index by type and then year.
    // the accumulator will count the number per type per year
    $finalArray[ $ix[0] ][ $ix[1] ]++;
    // keep an array of years
    $years[ $ix[1] ]++;
}

// sort arrays by key
ksort($finalArray);
ksort($years);

// print out the column headings
echo "Year\t" . implode("\t", array_keys($finalArray) ) . "\n";

// now add the data
foreach (array_keys($years) as $y) {
    echo $y;
    // for each type, check the frequency for the year
    // print '0' if the year does not exist
    foreach ($finalArray as $type => $year) {
        if (array_key_exists($y, $year)) {
            echo "\t" . $year[$y];
        } else {
            echo "\t0";
        }
    }
    echo "\n";
}
$finalArray = array();
$years = array();

foreach ($array1 as $ix) {
    // $ix[0] is typeNN, $ix[1] is year.
    // index by type and then year.
    // the accumulator will count the number per type per year
    $finalArray[ $ix[0] ][ $ix[1] ]++;
    // keep an array of years
    $years[ $ix[1] ]++;
}

// sort arrays by key
ksort($finalArray);
ksort($years);

// print out the column headings
echo "Year\t" . implode("\t", array_keys($finalArray) ) . "\n";

// now add the data
foreach (array_keys($years) as $y) {
    echo $y;
    // for each type, check the frequency for the year
    // print '0' if the year does not exist
    foreach ($finalArray as $type => $year) {
        if (array_key_exists($y, $year)) {
            echo "\t" . $year[$y];
        } else {
            echo "\t0";
        }
    }
    echo "\n";
}
Year    type01  type02  type03  type09
1995    3       0       0       2
1996    0       0       1       0
1997    0       1       0       0
1998    0       0       0       1
1999    0       1       0       0
$sorted = array();
$types = array();
array_walk($array1, function($v) use (&$sorted, &$types){
   if( !isset($sorted[$v[1]]) )
       $sorted[$v[1]] = array();
   $sorted[$v[1]][] = $v[0];
   $types[] = $v[0];
});

// filter types
$types = array_unique($types);
sort($types);

// sort year
ksort($sorted);

echo '----' . implode(' ,', $types) . "\r\n";
foreach($sorted as $year => $data)
{   echo $year . ' - ';
    $count = array_count_values($data);

   foreach($types as $type)
   {  
      if( !isset($count[$type]))
      {
          echo '0,';
      } else {
          echo $count[$type].',';
      }
   }
   echo "\r\n";
}
$finalArray = array();
$years = array();

foreach ($array1 as $ix) {
    // $ix[0] is typeNN, $ix[1] is year.
    // index by type and then year.
    // the accumulator will count the number per type per year
    $finalArray[ $ix[0] ][ $ix[1] ]++;
    // keep an array of years
    $years[ $ix[1] ]++;
}

// sort arrays by key
ksort($finalArray);
ksort($years);

// print out the column headings
echo "Year\t" . implode("\t", array_keys($finalArray) ) . "\n";

// now add the data
foreach (array_keys($years) as $y) {
    echo $y;
    // for each type, check the frequency for the year
    // print '0' if the year does not exist
    foreach ($finalArray as $type => $year) {
        if (array_key_exists($y, $year)) {
            echo "\t" . $year[$y];
        } else {
            echo "\t0";
        }
    }
    echo "\n";
}
Year    type01    type02    type03    type09
1995    3         0         0         2
1996    0         0         1         0
1997    0         1         0         0
1998    0         0         0         1
1999    0         1         0         0
$sorted = array();
$types = array();
array_walk($array1, function($v) use (&$sorted, &$types){
   if( !isset($sorted[$v[1]]) )
       $sorted[$v[1]] = array();
   $sorted[$v[1]][] = $v[0];
   $types[] = $v[0];
});

// filter types
$types = array_unique($types);
sort($types);

// sort year
ksort($sorted);

echo '----' . implode(' ,', $types) . "\r\n";
foreach($sorted as $year => $data)
{    echo $year . ' - ';
    $count = array_count_values($data);

   foreach($types as $type)
   {  
      if( !isset($count[$type]))
      {
          echo '0,';
      } else {
          echo $count[$type].',';
      }
   }
   echo "\r\n";
}
$finalArray = array();
$years = array();

foreach ($array1 as $ix) {
    // $ix[0] is typeNN, $ix[1] is year.
    // index by type and then year.
    // the accumulator will count the number per type per year
    $finalArray[ $ix[0] ][ $ix[1] ]++;
    // keep an array of years
    $years[ $ix[1] ]++;
}

// sort arrays by key
ksort($finalArray);
ksort($years);

// print out the column headings
echo "Year\t" . implode("\t", array_keys($finalArray) ) . "\n";

// now add the data
foreach (array_keys($years) as $y) {
    echo $y;
    // for each type, check the frequency for the year
    // print '0' if the year does not exist
    foreach ($finalArray as $type => $year) {
        if (array_key_exists($y, $year)) {
            echo "\t" . $year[$y];
        } else {
            echo "\t0";
        }
    }
    echo "\n";
}
Source Link

Extracting data from an array of arrays, PHP style

I was browsing Stack Overflow recently and saw a PHP question about rearranging an array of arrays for printing. The initial data structure looked like this:

$array1 = array(
    array("type01",1995),
    array("type03",1996),
    array("type01",1995),
    array("type09",1998),
    array("type09",1995),
    array("type02",1997),
    array("type01",1995),
    array("type02",1999),
    array("type09",1995)
);

For printing, the number of occurrences of each pairing--type and year--had to be counted and a table of frequencies made with type as columns and the years as the rows, i.e.

Year    type01  type02  type03  type09
1995    3       0       0       2
1996    0       0       1       0
1997    0       1       0       0
1998    0       0       0       1
1999    0       1       0       0

(the actual table formatting was not critical)

Someone else answered the question, and used the following code:

$sorted = array();
$types = array();
array_walk($array1, function($v) use (&$sorted, &$types){
   if( !isset($sorted[$v[1]]) )
       $sorted[$v[1]] = array();
   $sorted[$v[1]][] = $v[0];
   $types[] = $v[0];
});

// filter types
$types = array_unique($types);
sort($types);

// sort year
ksort($sorted);

echo '----' . implode(' ,', $types) . "\r\n";
foreach($sorted as $year => $data)
{   echo $year . ' - ';
    $count = array_count_values($data);

   foreach($types as $type)
   {  
      if( !isset($count[$type]))
      {
          echo '0,';
      } else {
          echo $count[$type].',';
      }
   }
   echo "\r\n";
}

I come from a Perl background, and I would use the following code to solve the problem:

$finalArray = array();
$years = array();

foreach ($array1 as $ix) {
    // $ix[0] is typeNN, $ix[1] is year.
    // index by type and then year.
    // the accumulator will count the number per type per year
    $finalArray[ $ix[0] ][ $ix[1] ]++;
    // keep an array of years
    $years[ $ix[1] ]++;
}

// sort arrays by key
ksort($finalArray);
ksort($years);

// print out the column headings
echo "Year\t" . implode("\t", array_keys($finalArray) ) . "\n";

// now add the data
foreach (array_keys($years) as $y) {
    echo $y;
    // for each type, check the frequency for the year
    // print '0' if the year does not exist
    foreach ($finalArray as $type => $year) {
        if (array_key_exists($y, $year)) {
            echo "\t" . $year[$y];
        } else {
            echo "\t0";
        }
    }
    echo "\n";
}

Granted, the two pieces of code format the table slightly differently, but is one approach "better"--more efficient, more in line with standard PHP coding practices--than the other?

I'm also aware that my code generates notices about undefined index/offsets because I'm used to Perl's autovivification of data structures. Is this something to worry about or not?