2014-09-01 7 views
1

У меня есть файл CSV, назовите его data.csv, который выглядит следующим образом:Как объединить значения из нескольких строк с одинаковым идентификатором в запятую с уникальным идентификатором

id,position,data 
1,1,Data text 
1,2,Data text 2 
1,3,Data text 3 
2,1,Data text x 
2,2,Data text y 

Что мне нужно, чтобы сростить значения в поле data в одном для всех строк с одинаковыми id. Затем напечатайте эти вновь полученные строки в другом CSV-файле.

Мне удалось упорядочить значения в массиве, но при преобразовании в файл CSV он сохраняет только один из них.

Вот мой код

$file = 'data.csv'; 
$tsvFile = new SplFileObject($file); 
$tsvFile->setFlags(SplFileObject::READ_CSV); 
$tsvFile->setCsvControl(","); 

foreach ($tsvFile as $line => $row) { 
    if ($line > 0) { 
      $newData[$row[0]] = array('id'=>$row[0], 'position'=>$row[1], 'data'=>$row[2]); 
      $newData[$row[1]] = $row[2]; 
    } 
} 
// 
echo '<pre>'; 
var_dump($newData); 
// 
$fp = fopen('data2.csv', 'w'); 
foreach ($newData as $fields) { 
    fputcsv($fp, $fields); 
} 
fclose($fp); 

В конце концов, результирующий файл CSV должен выглядеть следующим образом:

id,data 
"1","Data text, Data text 1, Data text 2" 
"2","Data text x, Data text y" 
+0

Просто для того, чтобы получить прямо: у вас есть CSV ('data.csv'), который выглядит как первый выделенный блок, и вы хотите разобрать его в другом CSV-файле, который выглядит как последний выделенный блок? – Overflowh

+0

точно. Thx ... – Dario

ответ

0

Ну, я думаю, что вы могли бы сделать то, что вы просите в более простой способ.

Я только что использовал fgetcsv() и fputcsv() функции для обработки выделения и вставки хорошо сформированной и хорошо отформатированной строки из/в файл.

$output = array(); 

if ($in_handle = fopen('data.csv', 'r')) { 
    // discard the first line, the one with the names of the fields 
    $input = fgetcsv($in_handle); 

    // get an array out of a row from the file data.csv 
    while ($input = fgetcsv($in_handle)) { 
     // create an array with only the needed fields 
     $current_row = array(
      'id' => $input[0], 
      'data' => $input[2] 
     ); 

     if (array_key_exists($current_row['id'], $output)) { 
      $output[$current_row['id']]['data'] .= ' ' . $current_row['data']; 
     } else { 
      $output[$current_row['id']] = $current_row; 
     } 
    } 

    fclose($in_handle); 

    if ($out_handle = fopen('new_file.csv', 'w')) { 
     // recreate the first line of the file deleted before 
     $fields_names = array('id', 'data'); 
     fputcsv($out_handle, $fields_names); 

     // begins at 1 because there isn't any value before 
     for ($i = 1; $i <= count($output); ++$i) 
      fputcsv($out_handle, $output[$i]); 
    } 

    fclose($out_handle); 
} 

Вот вход я использовал для тестирования сценария:

id,position,data 
1,1,first string 
1,2,second string 
1,3,third string 
2,1,fourth string 
2,2,fifth string 

А вот выходной файл я получен:

id,data 
1,"first string second string third string" 
2,"fourth string fifth string" 

Как вы можете видеть, data часть строк теперь цитируется. Именно так стандартная CSV обрабатывает строки.

+0

Точно!, Thx много! – Dario

+0

it return Предупреждение: fputcsv() ожидает, что параметр 2 будет массивом, null указан в – Dario

+0

Это __is__ массив. Просто проверьте свой файл и счетчик 'for'. Я сделал '$ i', начиная с' 1', потому что раньше не было индекса, как сказано в комментарии выше цикла. Теперь вам нужно адаптировать его к вашему коду. – Overflowh

Смежные вопросы