不确定是什么标题...
.csv示例:
tennis,soccer,sports
car,plane,things
jeans,shirt,things
我的最终理想目标 应该是一个如下数组:
Array
(
[sports] => Array
(
[0] => tennis
[1] => soccer
)
[things] => Array
(
[0] => car
[1] => plane
[2] => jeans
[3] => shirt
)
)
这是我最近达到上述目标的尝试(经过多次尝试):
<?php
$f_name = 'test.csv';
// Stores all csv data
$csv_data = array_map('str_getcsv', file($f_name));
$c = count($csv_data);
$tmp = array();
$data_for_email = array();
for ($i = 0; $i < $c; $i++) {
// Remove last element and make it a key
$le = array_pop($csv_data[$i]);
$tmp[$le] = $csv_data[$i];
$data_for_email = array_merge_recursive($data_for_email, $tmp); // MEMORY ERROR
}
print_r($data_for_email);
?>
这就是我得到的结果:
Array
(
[sports] => Array
(
[0] => tennis
[1] => soccer
[2] => tennis
[3] => soccer
[4] => tennis
[5] => soccer
)
[things] => Array
(
[0] => car
[1] => plane
[2] => jeans
[3] => shirt
)
)
如您所见,我在[sports]
数组中得到了.csv第1行的副本。
我的要求的详细说明:
key
。values
的其余两个字段(第1个和第2个)变为key
。 P.S。之后,我可以解析该数组(以删除重复的值),但是真正的.csv文件很大,处理它变得太慢,并且在用// MEMORY ERROR
标记的行上收到以下错误:< / p>
致命错误:允许的内存大小为134217728字节已耗尽
我尝试增加内存限制,但我希望尽可能避免这种情况。
答案 0 :(得分:1)
应该容易一些。不需要array_merge_recursive
:
foreach($csv_data as $row) {
$key = array_pop($row);
if(!isset($data_for_email[$key])) {
$data_for_email[$key] = [];
}
$data_for_email[$key] = array_merge($data_for_email[$key], $row);
}
答案 1 :(得分:0)
更高的内存效率将是:
fgetcsv
一次读取一行代码:
$handle = fopen($f_name, 'r');
if (!$handle) {
// Your error-handling
die("Couldn't open file");
}
$data_for_email = array();
while($csvLine = fgetcsv($handle)) {
// Remove last element and make it a key
$le = array_pop($csvLine);
if (isset($data_for_email[$le])) {
$data_for_email[$le] = array_merge($data_for_email[$le], $csvLine);
} else {
$data_for_email[$le] = $csvLine;
}
}
fclose($handle);
答案 2 :(得分:0)
您只需要在每个循环中初始化$tmp
,即可解决您的问题。检查以下代码:
for ($i = 0; $i < $c; $i++) {
// Remove last element and make it a key
$le = array_pop($csv_data[$i]);
$tmp = []; //Reset here
$tmp[$le] = $csv_data[$i];
$data_for_email = array_merge_recursive($data_for_email, $tmp); // MEMORY ERROR
}
希望它对您有帮助。
答案 3 :(得分:0)
使用密钥名称来获得唯一列表。如果有大量数据,它比合并便宜。
RaycastHit hit;
hit.point;
输出:
$handle = fopen('test.csv', 'r');
$res = [];
while ($data = fgetcsv($handle)) {
list($first, $second, $type) = $data;
$res[$type] = ($res[$type] ?? []);
array_map(function($e)use(&$res, $type) {
$res[$type][$e] = $e;
}, [$first, $second]);
}
答案 4 :(得分:0)
我也做了点什么,但是现在其他的都快了。 :D 我已经做到了,它并没有完全满足您的要求,但是也许可以进一步帮助您。
不幸的是,我现在还没有进一步想告诉你:)
这是您的index.php(或任何称为文件的文件。)
<?php
include "Data.php";
$f_name = 'in.csv';
// Stores all csv data
$csv_data = array_map('str_getcsv', file($f_name));
$c = count($csv_data);
$tmp = array();
$data_for_email = array();
foreach ($csv_data as $data){
$key = array_pop($data);
array_push($data_for_email,new Data($data,$key));
}
foreach ($data_for_email as $data){
array_push($tmp,$data->getValue());
}
foreach ($tmp as $value){
print_r($value);
echo "<br>";
}
,这里是数据类:
<?php
class Data
{
private $value = [];
public function __construct($data, $key)
{
$this->value[$key]=$data;
}
/**
* @return array
*/
public function getValue()
{
return $this->value;
}
}
作为输出,您将像这样:
Array ( [sports] => Array ( [0] => tennis [1] => soccer ) )
Array ( [things] => Array ( [0] => car [1] => plane ) )
Array ( [things] => Array ( [0] => jeans [1] => shirt ) )
ps: 当然还有另一个功能可以总结相同的键,但是不知何故我现在什么都找不到... 希望对您有所帮助:)