解析CSV以获取特定列

时间:2013-12-12 14:49:44

标签: php fgetcsv

我有一个包含多个标题的CSV文件。

我只需要这些列中的大约5列。

我正在尝试将这些变为更易于管理的格式(变量?),以便我可以检查它们的值。

我有以下代码:

    $headers    = array('NAME', 'EMAIL');
    $picked     = array();
    $theData    = array();
    $isFirstRow = true;
    if (($handle = fopen($uploadedFile, "r")) !== FALSE) {
        while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
            $numCols = count($data);
            $row     = array();

            if($isFirstRow) {
                for($c=0; $c<$numCols; $c++) {
                    if(!in_array($data[$c], $headers)) {
                       continue;
                    } else {
                        $picked[] = $c;
                        $isFirstRow = false;
                    }
                }
            } else {
                for($c=0; $c < $numCols; $c++) {
                    if(in_array($c, $picked)) {
                        $row[] = $data[$c];
                        $theData[] = $row;
                    }
                }
            }
        }
        fclose($handle);


    }
    var_dump($theData);

这输出以下内容:

array (size=xxxxxx)
  0 => 
    array (size=1)
      0 => string 'John Doe' (length=8)
  1 => 
    array (size=2)
      0 => string 'John Doe' (length=8)
      1 => string 'johndoe@test.com' (length=16)
  2 => 
    array (size=1)
      0 => string 'Jane Doe' (length=8)
  3 => 
    array (size=2)
      0 => string 'Jane Doe' (length=8)
      1 => string 'janedoe@test.com' (length=16)

显然这不是预期的输出

我想要更像的东西:

array (size=xxxx)
  0 =>
    array (size=1)
      0 => string 'John Doe' (length=8)
      1 => string 'johndoe@test.com' (length=16)
  1 =>
    array (size=2)
      0 => string 'Jane Doe' (length=8)
      1 => string 'janedoe@test.com' (length=16)

我不确定为什么要添加额外的阵列。

有人有想法吗?

由于

修改

我的CSV看起来像这样;

NAME,EMAIL
John Doe,johndoe@test.com
Jane Doe,janedoe@test.com

2 个答案:

答案 0 :(得分:1)

修改:新答案。

所以有一个有点复杂的解决方案:

  • 获取您的CSV数据
  • 将数字键数据与所有可用标题相结合,为您提供键=&gt;值数组
  • 将此与您的ALLOWED标题相交
  • 将其添加到最终数据阵列
  • 删除标题行

我们走了。读起来很糟糕,但似乎很好。由于所有数组操作都是基于C的,因此它应该比在PHP中操作数千行更快。

    $availableHeaders = array('NAME', 'THING', 'EMAIL');
    $headers    = array('NAME', 'EMAIL');
    $theData    = array();

    if (($handle = fopen($uploadedFile, "r")) !== FALSE) {
        while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
            $theData[] = array_intersect_key(array_combine(array_values($availableHeaders), array_values($data)), array_flip($headers));
        }
        fclose($handle);
    }

    array_shift($theData); // Remove headers

答案 1 :(得分:0)

示例.csv:

IGNORE1,NAME,EMAIL,IGNORE2,IGNORE3
-1,John Doe,johndoe@test.com,-1,-1
-1,Jane Doe,janedoe@test.com,-1,-1

代码:

$headers    = array('3' => 'NAME', '4' => 'EMAIL');
$theData    = array();
$isFirstRow = true;
$rowsToKeep = array();
if (($handle = fopen($uploadedFile, "r")) !== FALSE) {
    while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
        if ( $isFirstRow ) {
            $rowsToKeep = array_intersect($data, $headers);
            $theData[] = $rowsToKeep;
            $isFirstRow = false;
        } else {    
            $theData[] = array_intersect_key($data, $rowsToKeep);
        }
    }
    fclose($handle);
}

产地:

Array
(
    [0] => Array
        (
            [1] => NAME
            [2] => EMAIL
        )

    [1] => Array
        (
            [1] => John Doe
            [2] => johndoe@test.com
        )

    [2] => Array
        (
            [1] => Jane Doe
            [2] => janedoe@test.com
        )

)