Was not really sure on what question's title should be here...
Sample .csv :
tennis,soccer,sports
car,plane,things
jeans,shirt,things
My final, ideal , outcome should be an array that looks like this:
Array
(
[sports] => Array
(
[0] => tennis
[1] => soccer
)
[things] => Array
(
[0] => car
[1] => plane
[2] => jeans
[3] => shirt
)
)
Here is my most recent attempt to achieve the outcome above (after many tries):
<?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);
?>
This is what I get as a result:
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
)
)
As you can see, I get duplicates of .csv's line 1 in [sports]
array.
More detailed description of my requirement:
key
in a new associative array. values
for that key
. PS I could parse that array (to remove duplicate values) afterwards, but the real .csv file is large and it becomes too slow to process it, and I receive the following error at the line which I marked with // MEMORY ERROR
:
Fatal Error: Allowed Memory Size of 134217728 Bytes Exhausted
I tried increasing the memory limit but I'd prefer to avoid this if possible.
Should be a little easier. No need for 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);
}
More memory efficient would be:
fgetcsv
reads one line at a time Code:
$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);
You just need to initialize $tmp
in every loop which will resolve your problem. Check below code:
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
}
Hope it helps you.
Use the name for the key to get a unique list. It is cheaper than merge if there is a lot of data.:
$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]);
}
output:
Array
(
[sports] => Array
(
[tennis] => tennis
[soccer] => soccer
)
[things] => Array
(
[car] => car
[plane] => plane
[jeans] => jeans
[shirt] => shirt
)
)
i made something, too, but now the others were faster. :D I've made it oop, it doesn't quite come out what you wanted but maybe it helps you further.
I have not come any further now, unfortunately, wanted to show it to you anyway :)
Here is your index.php ( or whatever the file is called. )
<?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>";
}
and here the class Data:
<?php
class Data
{
private $value = [];
public function __construct($data, $key)
{
$this->value[$key]=$data;
}
/**
* @return array
*/
public function getValue()
{
return $this->value;
}
}
as output you bekome something like that:
Array ( [sports] => Array ( [0] => tennis [1] => soccer ) )
Array ( [things] => Array ( [0] => car [1] => plane ) )
Array ( [things] => Array ( [0] => jeans [1] => shirt ) )
ps: surely there is another function that summarizes the same keys, but somehow i don't find anything now... I hope it helps :)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.