2013-12-12 91 views
1

我有一個包含多個標題的CSV文件。解析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 '[email protected]' (length=16) 
    2 => 
    array (size=1) 
     0 => string 'Jane Doe' (length=8) 
    3 => 
    array (size=2) 
     0 => string 'Jane Doe' (length=8) 
     1 => string '[email protected]' (length=16) 

顯然,這不是預期的輸出

我想更多的東西一樣:

array (size=xxxx) 
    0 => 
    array (size=1) 
     0 => string 'John Doe' (length=8) 
     1 => string '[email protected]' (length=16) 
    1 => 
    array (size=2) 
     0 => string 'Jane Doe' (length=8) 
     1 => string '[email protected]' (length=16) 

我不確定爲什麼要添加額外的數組。

任何人有想法?

感謝

編輯

我的CSV看起來是這樣的;

NAME,EMAIL 
John Doe,[email protected] 
Jane Doe,[email protected] 
+0

你的if/else塊沒有括號,但兩行代碼。 – kinghfb

+0

你的csv看起來像什麼? – veelen

+0

@veelen我已經添加了CSV信息 –

回答

0

編輯:New answer。

所以這是一個有點複雜的解決方案,這是否:

  • 注意到您的CSV數據
  • 所有可用頭結合的數字鍵的數據,讓您一鍵=>值數組
  • 相交這你允許的頭
  • 一下添加到最終的數據陣列
  • 刪除標題行

我們走了。閱讀很糟糕,但似乎沒有問題。因爲所有的數組操作都是基於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 
+0

這會替換當前的'$ theData []'數組嗎? –

+0

這將只爲每個條目添加這兩列。但是,我只是仔細檢查fgetcsv是否分配鍵或數字索引。我有一個偷偷摸摸的懷疑它只是用戶數字索引... – kinghfb

+0

目前的問題是,我添加的列越多,添加的數組越多。 1列= 1陣列,2列2陣列(作爲我的問題)3列3陣列等etc等 –

0

示例.csv文件:

IGNORE1,NAME,EMAIL,IGNORE2,IGNORE3 
-1,John Doe,[email protected],-1,-1 
-1,Jane Doe,[email protected],-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] => [email protected] 
     ) 

    [2] => Array 
     (
      [1] => Jane Doe 
      [2] => [email protected] 
     ) 

) 
+0

如果列的順序不同,會發生什麼情況?這就是爲什麼我以列名爲基礎,而不是在標題中的關鍵。 –

+0

我的回覆包括測試代碼所需的一切。它不關心你的列的順序。它使用你在$ headers中指定的名稱來標識應該存儲在$ theData中的列。我強烈建議在http://php.net/manual/en/ref.array.php上了解這些功能。 – Dave