当缺少数组 key-value 对时,删除 csv 中乱序的列数据

Remove out of order column data in csv when array key-value pair is missing

我有一个多维数组,其中一些数组缺少在其他数组中找到的 key-value 对。当我转换为 csv(在本例中为 tab-delimited)时,一行中的列单元格向左移动并替换缺失的 key/value。例如,这个数组:

array
  (
  array("Make" => "Volvo", "Color" => "red", "Quantity" => 18),
  array("Make" => "BMW", "Color" => "blue", "Quantity" => 13),
  array("Make" => "Saab", "Quantity" => 11),
  array("Make" => "Land Rover", "Color" => "green", "Quantity" => 15)
  );

版本 1

当我使用以下代码时:

$cfilename = 'result.csv';
$data = array
  (
  array("Make" => "Volvo", "Color" => "red", "Quantity" => 18),
  array("Make" => "BMW", "Color" => "blue", "Quantity" => 13),
  array("Make" => "Saab", "Quantity" => 11),
  array("Make" => "Land Rover", "Color" => "green", "Quantity" => 15)
  );

    //below creates csv
$fp = fopen($cfilename, 'w');
$header = false;
foreach ($data as $row)
{

fputcsv($fp, $row, chr(9));
}
fclose($fp);
return;

会给我这样的输出:

Volvo      |red    | 18
BMW        |blue   | 13
Saab       |11     | 
Land Rover |green  | 15

如果我使用键标签编写 headers,我可以让列正确排列。但在这种情况下,缺失的 key/value 对的单元格不是空的,而是列号打印在它的位置。

版本 2 此代码:

$cfilename = 'result.csv';
$data = array
  (
  array("Make" => "Volvo", "Color" => "red", "Quantity" => 18),
  array("Make" => "BMW", "Color" => "blue", "Quantity" => 13),
  array("Make" => "Saab", "Quantity" => 11),
  array("Make" => "Land Rover", "Color" => "green", "Quantity" => 15)
  );

//below creates csv
$fp = fopen($cfilename, 'w');
$header = false;
foreach ($data as $row)
{
    if (empty($header)) //creates header, chr(9) makes tab delimited
    {
        $header = array_keys($row);
        fputcsv($fp, $header, chr(9));
        $header = array_flip($header);
    }
    fputcsv($fp, array_merge($header, $row), chr(9)); //creates rows, chr(9) makes tab delimited
}
fclose($fp);
return;

结果:

Make       | Color | Quantity
-----------|-------|----
Volvo      |red    | 18
BMW        |blue   | 13
Saab       |1      | 11
Land Rover | green | 15

请注意,"Saab" 行中颜色下方的“1”。

如果版本 1 没有标题,让任何一个版本都能正常工作,我总是可以将该行添加到 tab-delimited 输出文件中。

如果字段不存在,为什么不直接将其设置为空字符串?

$cfilename = 'result.csv';
$data = array(
    array("Make" => "Volvo", "Color" => "red", "Quantity" => 18),
    array("Make" => "BMW", "Color" => "blue", "Quantity" => 13),
    array("Make" => "Saab", "Quantity" => 11),
    array("Make" => "Land Rover", "Color" => "green", "Quantity" => 15)
);

//below creates csv
$fp = fopen($cfilename, 'w');
$header = false;
$fields = ['Make', 'Color', 'Quantity'];
foreach ($data as $row)
{
    foreach($fields as $field) {
        if (!array_key_exists($field, $row) {
            $row[$field] = '';
        }
    }
    fputcsv($fp, $row, chr(9));
}
fclose($fp);
return;

值为 1,因为这是 Color 键的 $header 数组中的值(您在合并之前翻转了它,所以现在不是 1 => "Color",而是 "Color" => 1).你可以做的就是将所有值设置为 NULL,或者一个空字符串,或者一个占位符,或者当没有值时你想要的任何东西,array_map():

<?php
$cfilename = 'result.csv';
$data = array
  (
  array("Make" => "Volvo", "Color" => "red", "Quantity" => 18),
  array("Make" => "BMW", "Color" => "blue", "Quantity" => 13),
  array("Make" => "Saab", "Quantity" => 11),
  array("Make" => "Land Rover", "Color" => "green", "Quantity" => 15)
  );
echo "<pre>";
//below creates csv
$fp = fopen($cfilename, 'w');
$header = false;
foreach ($data as $row)
{
    if (empty($header)) //creates header, chr(9) makes tab delimited
    {
        $header = array_keys($row);
        fputcsv($fp, $header, chr(9));
        $header = array_flip($header);
        $header = array_map(function($header) { return "";}, $header);
    }
    // var_dump($header);
    fputcsv($fp, array_merge($header, $row), chr(9)); //creates rows, chr(9) makes tab delimited

}
fclose($fp);
return;

Demo (without saving to file, only printing to screen)