Naming each line in array in for each loop - php

I have multiple arrays, where I want to name each array at the end of the for each loop.
The code php code:
<?php
$csv = array_map("str_getcsv", file("translations/dk.csv"));
foreach ($csv as $line){
if ($line[1] != NULL){
$line[0] = $line[1];
}
print_r($line[0]);
print_r("<br />");
}
fclose($csv);
?>
Example of the arrays.
Array ( [0] => Search and Save [1] => Søg og Spar på Hoteller )
Array ( [0] => Where are you going? [1] => Hvor skal du hen? )
Now the output of line[0] is each time the foreach loop runs naturally with a different value. But I need to name each $line[0] on every loop so I can access them afterwards. How do I do this ?

First of all, you shouldn't use file() to split up the lines; CSV records may span multiple lines.
$f = fopen("translations/dk.csv", 'rt');
$csv = array();
while (($data = fgetcsv($f)) !== false) {
$csv[] = $data;
}
fclose($f);
Second, to select the first column from the array you can use array_column():
$results = array_column($csv, 0);
// "Search and Save", "Where are you going?"]

Maybe you're looking for something like this:
<?php
$csv = array_map("str_getcsv", file("translations/dk.csv"));
$results = array();
foreach ($csv as $k => $line){
if ($line[1] != NULL){
$line[0] = $line[1];
$results[$k] = $line[0];
}
print_r($line[0]);
print_r("<br />");
}
print_r($results);
?>

Related

check index of columns in key of an array and remove columns with value 0

I have a php code that takes the matched rows of a csv file and puts them in an array.
my csv file looks like this:
Company,Produkt,Sortiment name,31,32,33,34,35,36,37,38 //these are shoe sizes
Dockers,AD1234,Sort A,2,3,5,3,2,1,0,0 //and these numbers are how many pairs of shoes
Addidas,AB1234,Sort B,2,2,1,4,,0,0,4,3
Nike,AC1234,Sort C,0,2,0,1,4,0,4,3
Dockers,AE1234,Sort D,0,1,2,3,4,1,0,2
and my php code is
$csv = file_get_contents($_SERVER['DOCUMENT_ROOT'] . 'CsvTest/Sortiment.csv');
$input = 'Company'; // column
$value = 'Dockers'; // what value of that column
$csv = array_map("str_getcsv", explode(PHP_EOL, $csv));
$keys = array_shift($csv);
$key = array_search($input, $keys);
$sortiment_array = array();
while ($line = array_shift($csv)) {
if ($line[$key] == $value) {
$line = implode(',', $line) . PHP_EOL;
$sortiment_array[] = $line;
}
}
so var_dump($sortiment_array); will give me the following
array(2) {
[0]=>
string(39) "Dockers,AD1234,Sort A,2,3,5,3,2,1,0,0"
[1]=>
string(39) "Dockers,AE1234,Sort D,0,1,2,3,4,1,0,2"
}
What I would like to do is to have the 0 columns taken out from the array and so therefore I need to identify what pair of shoes was not 0 ? So I need the first row (which is the header for my case) to repeat itself for each key and take out the shoe size that had 0 pairs. basically my array should turn into something like:
array(2) {
[0]=>array(2)
['shoe size']=> "Producer,Produkt,Sortiment name,31,32,33,34,35,36" // no 37,38
['sortiment']=> "Dockers,AD1234,Sort A,2,3,5,3,2,1,"// no 0
[1]=>array(2)
['shoe size']=> "Producer,Produkt,Sortiment name,32,33,34,35,36,38" // no 31, 37
['sortiment']=> "Dockers,AE1234,Sort D,1,2,3,4,1,2"
}
Basically in 'shoe size' sizes should be taken out where the matched row has 0 pairs for that size. I hope I can explain it. I tried my best. Any suggestions?
If all the rows in the data are the same size, you can combine the keys and values for each line that matches, then filter that to remove the zeros.
while ($line = array_shift($csv)) {
if ($line[$key] == $value) {
// combine keys and values, and filter to remove zeros
$filtered = array_filter(array_combine($keys, $line));
// separate the resulting keys and values and add them to your output array
$sortiment_array[] = [
'shoe size' => implode(',', array_keys($filtered)),
'sortiment' => implode(',', $filtered)
];
}
}
<?php
$csv = file_get_contents($_SERVER['DOCUMENT_ROOT'] . 'CsvTest/Sortiment.csv');
$input = 'Company'; // column
$value = 'Dockers'; // what value of that column
$csv = array_map("str_getcsv", explode(PHP_EOL, $csv));
$keys = array_shift($csv);
$key = array_search($input, $keys);
$sortiment_array = array();
while ($line = array_shift($csv)) {
if ($line[$key] == $value) {
$lineStr = implode(',', $line) . PHP_EOL;
$outputKeys = [];
$outputLine = [];
// Look through $line to find non-'0' elements and for each of them,
// add the corresponding elements to $outputKeys and $outputLine:
for( $i=0; $i < sizeof($keys); $i++ ) {
if ( $line[$i] !== '0' ) { // No '0' in this slot so add this slot to $outputKeys and $outputLine:
$outputKeys[] = $keys[$i];
$outputLine[] = $line[$i];
}
}
// Join $outputKeys and $outputLines back into a string:
$sortiment_array[] = [
join(',', $outputKeys),
join(',', $outputLine)
];
}
}
print_r($sortiment_array);
You can implement the logic which does it for a pair of arrays, the first being the template (header row) and the second the csv row after the header.
function nonZeros($template, $row) {
$output = [
'shoe_size' => [],
'sortiment' => []
];
for ($index = 0; $index < count($row); $index++) {
if ($row != 0) {
$output['shoe_size'][]=$template[$index];
$output['sortiment'][]=$row[$index]
}
}
return $output;
}
and then you can loop the lines and call nonZeros, passing the corresponding arrays.

CSV overwrite line if same date else append to new line

I want to write $totalToday data from API to csv file. If current date not existed, append new record for current date. I've came with following solution.
$search = date("d/m/Y");
$lines = file('data.csv');
$line_number = false;
foreach($lines as $key => $line) {
$line_number = (strpos($line, $search) !== FALSE);
}
if(!$line_number){
$entry = array(date("d/m/Y"), $totalToday);
$fp = fopen('data.csv', 'a');
fputcsv($fp, $entry);
fclose($fp);
}
My problem is $totalToday from API get updated time to time. I want to record the latest update. so I replaced $search = date("d/m/Y"); with $search = date("d/m/Y"), $totalToday now I have multiple record for same date in my data.csv. I want to overwrite the current date record with very latest data without append to new line. How to accomplish my requirement
Example data: (first rows)
date,newCases,totalToday
13/04/2020,21,110
14/04/2020,26,125
14/04/2020,30,130
I want to replace 14/04/2020,26,125 with 14/04/2020,30,130
One approach could be this:
<?php
$search = '14/04/2020';
$other_data_from_api = array(188,102);
$lines = file('data.csv');
//Create a new array and set all dates as keys
//The latest set key would be the current
$new_arr = array();
foreach($lines as $line) {
$exp = explode(',', $line);
$new_arr[$exp[0]] = array($exp[1], $exp[2]);
}
/*
So in your example:
13/04/2020,21,110
14/04/2020,26,125
14/04/2020,30,130
the array $new_arr would contain:
[13/04/2020] => Array
(
[0] => 21
[1] => 110
)
[14/04/2020] => Array
(
[0] => 30
[1] => 130
)
*/
//Rewrite the whole file with values from this new array
$fp = fopen('data.csv', 'w');
foreach($new_arr as $key=>$line) {
$entry = $key . ',' . implode(',', $line);
fputs($fp, $entry);
}
fclose($fp);
You could also:
//Rewrite the whole file with values from this new array
//And include the actual data from the API
//(Then 188,102 would be included with the data of the $search variable)
$fp = fopen('data.csv', 'w');
foreach($new_arr as $key=>$line) {
if ($search == $key) {
$entry = $search . ',' . implode(',', $other_data_from_api);
}
else {
$entry = $key . ',' . implode(',', $line);
}
fputs($fp, $entry);
}
fclose($fp);

PHP script to rearrange csv data and output as csv

I have the following data in a csv file.
I need to rearrange the data and concate it into 2 columns. the columns will be SKU and Feature. Where SKU = SKU and Feature will be derivative from other columns in the following format.
For yellow marked row: Feature column data will be: Edge:Square Edge;Wide Plank|Finish:Glossy;Smooth|Grade:A(Select & Better/Prestige)|Installation Location:Second Floor;Main Floor........
I could parse the csv and stucked.
$lines = explode( "\n", file_get_contents( '3b.csv' ) );
$headers = str_getcsv( array_shift( $lines ) );
$data = array();
foreach ( $lines as $line ) {
$row = array();
foreach ( str_getcsv( $line ) as $key => $field )
if($headers[$key]=='sku'){
$row[ $headers[ $key ] ] = str_replace(",",";",$field);
}
if($headers[$key]!='sku' && $field!='') {
$row['feature'] = $headers[ $key ].":".str_replace(",",";",$field)."|";
}
$row = array_filter( $row );
$data[] = $row;
}
echo "<pre>";
print_r($data);
echo "</pre>";
Anyone please help me to do this or suggest any script to do this.
You haven't provided the actual text of your incoming csv files, so I will assume that parsing it normally will work properly.
I have borrow my script from your next two questions to unconditionally process your data.
The header row's data is used as a lookup array for the feature names.
Code: (untested)
$file = fopen("3b.csv", "r");
$headers = fgetcsv($file);
$final_array = [];
while (($row = fgetcsv($file)) !== false) {
$sku = $row[0];
unset($row[0]);
foreach ($row as $featureNameIndex => $featureValues) {
foreach (explode(',', $featureValues) as $featureValue) {
$final_array[] = [
'sku' => $sku,
'feature' => "{$headers[$featureNameIndex]}:{$featureValue}"
];
}
}
}
fclose($file);
var_export($final_array);
This approach will generate an indexed array of associative arrays -- each containing two-elements.
Features with multiple values are divided and stored as separate subarrays.

PHP Read csv data without first line

I want to store csv columns data into array
I have did this so far.
$csvfile = file('testfile.csv');
$csvData = [];
foreach ($csvfile as $key => $line) {
$csvData[] = str_getcsv($line);
}
This works fine but the first line also include in array
I want to skip first line
Remove the first element of the array with array_shift().
$csvfile = file('testfile.csv');
array_shift($csvfile);
$csvData = array_map('str_getcsv', $csvfile);
or you can do like this
$csvfile = file('testfile.csv');
unset($csvfile[0]);
$csvData = [];
foreach ($csvfile as $key => $line) {
$csvData[] = str_getcsv($line);
}

creating dynamic array in php

I have following records in text file, need to extract that record form text file and treat them as seperate array variables
r1=(1,2,3)|r2=(4,5,6)|r3=(1,2,3,4,5,7)|rn=(9,6,7,8) seperated by pipe(|)
I need to represent that as array use seperately like below
$r1= Array
(
[0] => 1
[1] => 2
[2] => 3
)
$r2=Array
(
[0] => 4
[1] => 5
[2] => 6
)
I have no idea how to do it, is it possible in php?
Just a plain regular expression to break up the string, followed by an explode on each group:
if (preg_match_all('#(\w+)=\(([\d,]*)\)#', $s, $matches)) {
foreach ($matches[2] as $i => $groups) {
$group_name = $matches[1][$i];
$$group_name = array_map('intval', explode(',', $groups));
}
}
print_r($r1);
print_r($r3);
print_r($rn);
You can use Eval
//Assuming you can pull the content from text file using fread
$temp = "r1=(1,2,3)|r2=(4,5,6)";
$temp=str_replace("=","=array",$temp);
$split=explode("|",$temp);
echo "<pre>";
foreach($split as $k=>$v){
$v="$".$v.";";
//Evaluate a string as PHP code .i.e You will get r1,r2 as a variable now which is array
eval($v);
}
print_r($r1);
print_r($r2);
$data = "r1=(1,2,3)|r2=(4,5,6)|r3=(1,2,3,4,5,7)|rn=(9,6,7,8)";
$arr = explode("|", $data);
$finArray = array();
foreach($arr as $key=>$value)
{
$single = explode('(', $value);
$finArray[] = explode(',', str_replace(')', '', $single[1]));
}
print_r($finArray);
can be done as:
$string="r1=(1,2,3)|r2=(4,5,6)|r3=(1,2,3,4,5,7)|rn=(9,6,7,8)";
$string=str_repla("r1=","",$string);
$yourArray=explode('|', $string);
This code will help you:--
<?php
$file = "/tmp/file1.txt"; // this is your file path
$f = fopen($file, "r");
while ( $line = fgets($f, 1000) ) {
print $line;
$a=explode('|',$line);
print_r($a); // I have explode based on | for you...
foreach($a as $key=>$value)
{
print_r($value);
}
fclose($file);
}
?>
""or""
$a="r1=(1,2,3)|r2=(4,5,6)|r3=(1,2,3,4,5,7)|rn=(9,6,7,8)";
$a=explode('|',$a);
print_r($a);
<?php
$file = "file.txt";
$f = fopen($file, "r");
while ( $line = fgets($f, 1000) ) {
$str = $line;
}
$str1 = explode("|",$str);
foreach($str1 as $temp) {
$str2 = explode("=",$temp);
$data[$str2[0]] = explode(",",trim($str2[1],"()"));
}
echo '<pre>';
print_r($data);
echo '</pre>';
?>
This will do your job.

Categories