Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Concatenate every n-th row of CSV file

Tags:

php

Consider data.csv:

"1","2","3","4"
"5","6","7","8"
"9","10","11","12"
"13","14","15","16"
"17","18","19","20"
"21","22","23","24"
"25","26","27","28"
"29","30","31","32"
"33","34","35","36"

I need to read this CSV and concatenate every nth, say every 3rd row to each other. So the desired output is:

array (
  [0] => 1,2,3,4,13,14,15,16,25,26,27,28    // row 1, 4 and 7
  [1] => 5,6,7,8,17,18,19,20,29,30,31,32    // row 2, 5 and 8
  [2] => 9,10,11,12,21,22,23,24,33,34,35,36 // row 3, 6 and 9
)

I need n to be variable, so it should be easy to, for instance, concatenate every 4th row as well:

array (
  [0] => 1,2,3,4,17,18,19,20,33,34,35,36    // row 1, 5 and 9
  [1] => 5,6,7,8,21,22,23,24                // row 2, 6
  [2] => 9,10,11,12,25,26,27,28             // row 3, 7
)

I now have this:

$path = "data.csv";
$row = 1;
if (($handle = fopen($path, "r")) !== FALSE) {
  while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
    for ($i = 1; $i <= 3; $i++) { // concatenate every 3rd row
      if ($row % $i == 0) $newrows[$i] .= implode(",", $data);
    }
    $row++;
  }
}

print_r($newrows);

But it doesn't work as expected since it outputs

Array (
  [1] => 1,2,3,45,6,7,89,10,11,1213,14,15,1617,18,19,2021,22,23,2425,26,27,2829,30,31,3233,34,35,36
  [2] => 5,6,7,813,14,15,1621,22,23,2429,30,31,32
  [3] => 9,10,11,1221,22,23,2433,34,35,36
)

Do you have a better idea? This mathematical logic always has me puzzled! :-)

like image 389
Pr0no Avatar asked Jul 15 '12 10:07

Pr0no


1 Answers

I don't have access to my server, right now, so I can't test it, but I think this simplified version of what you have should work.

$path = "data.csv";
$row = 1;

$groupings = 4; // group every n rows

if(($handle = fopen($path, "r")) !== FALSE)
{
    while(($data = fgetcsv($handle, 1000, ",")) !== FALSE)
    {
        $where = $row % $groupings; // which grouping is this?
        $newrows[$where] .= implode(",", $data).",";

        $row++;
    }
}

for($i = 0; $i < count($newrows); $i++)
{
    $newrows[$i] = substr($newrows[$i], 0, -1);
}

You need to run a second loop AFTER the initial while-loop since there's no way (that I can think of) to detect if the data being added is the last data that's going to be added to that grouping.

like image 99
Sandy Gifford Avatar answered Sep 27 '22 20:09

Sandy Gifford