2017-09-11 100 views
0

回調我有這樣的數據:使用array_filter()與返回數組

a|b|c|d|e|f|g 
h|i|j|k|l|m|n 
o|p|q|r|s|t|u 

我可以輕鬆地使用explode("\n", $data)把所有的線組成的數組(這是〜4.0GB文件)但現在我想通過使用基於垂直管道的explode()將其製作成多維陣列。這是我嘗試過的:

$data = explode("\n", './path-to-file.txt'); 
$results = array_filter($data, function ($el) { 
    return explode('|', $el); 
}); 

但是,這會產生一個以字符串形式的原始行的單維數組。

我該如何使用array_filter()來處理返回數組的回調?

編輯:使用foreach($data as $datum)並做explode()這種方式,但是當我試過了,我使用的RAM比文件的大小大約四倍的金額,這是不可取的。這似乎是一個使用回調函數的絕佳機會,但我似乎無法通過array_filter()來實現。

+2

我認爲使用array_map代替 –

+0

什麼是你用數組做什麼?文件可以一次處理一行,而不是全部讀入內存,或者你需要對它進行排序嗎? –

+0

這不是將文件數據存入數組,而是使用比文件大小更多的內存的方法。這是真正的數組本身:https://nikic.github.io/2011/12/12/How-big-are-PHP-arrays-really-Hint-BIG.html –

回答

1

array_filter()過濾要包括或排除它們的元素,並且期望true包括要排除的元素或false。使用array_map()

$data = explode("\n", './path-to-file.txt'); 
$results = array_map(function ($el) { 
    return explode('|', $el); 
}, $data); 

更內存高效的方式將逐行讀取:

if(($handle = fopen("./path-to-file.txt", "r")) !== false) { 
    while(($results[] = fgetcsv($handle, 0, "|")) !== false) {} 
} 
+0

當我這樣做時,我使用了〜34GB的內存這條路。有沒有「便宜」的方式來做到這一點? – David

+0

增加了另一種方式。 – AbraCadaver

+0

'fgetcsv()'比手動執行'foreach()'要慢很多,並且使用類似數量的RAM。事實上,這個腳本已經執行了11分鐘,並且與實際文件的大小相比仍然使用了大量的內存。但是'array_map()'是問題的答案,所以謝謝! – David