2017-09-11 64 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