I have an associative array in php, for example with the values:
"apple" => "green"
"banana" => "yellow"
"grape" => "red"
My question is, how can I write the keys and values for this array to a .txt file into two perfect columns?
By which I mean into two columns with a uniform distance between them all the way down
You can use str_pad() php function for the output.
http://php.net/manual/en/function.str-pad.php
Code:
<?php
$fruits = array( "apple" => "green",
"banana" => "yellow",
"grape" => "red" );
$filename = "file.txt";
$text = "";
foreach($fruits as $key => $fruit) {
$text .= str_pad($key, 20)." ".str_pad($fruit, 10 )."\n"; // Use str_pad() for uniform distance
}
$fh = fopen($filename, "w") or die("Could not open log file.");
fwrite($fh, $text) or die("Could not write file!");
fclose($fh);
Output:
apple green
banana yellow
grape red
// Getting the length dynamically version.
<?php
$fruits = array( "apple" => "green",
"banana" => "yellow",
"grape" => "red" );
$filename = "file.txt";
$maxKeyLength = 0;
$maxValueLength = 0;
foreach ($fruits as $key => $value) {
$maxKeyLength = $maxKeyLength < strlen( $key ) ? strlen( $key ) : $maxKeyLength;
$maxValueLength = $maxValueLength < strlen($value) ? strlen($value) : $maxValueLength ;
}
$text = "";
foreach($fruits as $key => $fruit) {
$text .= str_pad($key, $maxKeyLength)." ".str_pad($fruit, $maxValueLength )."\n"; //User str_pad() for uniform distance
}
$fh = fopen($filename, "w") or die("Could not open log file.");
fwrite($fh, $text) or die("Could not write file!");
fclose($fh);
Maybe a long shot, but you could possible do something like find the max array key length and then use that as a guide for how many spaces you want in between the words.
eg.
You could get the max array key length using strlen() like this:
$maxLength = 0;
foreach($array as $key => $item){
if(strlen($key) > $maxLength){
$maxLength = strlen($key);
}
}
$maxLength += 5; //or any spacing value here
And then use str_pad() to add padding to the word like this:
$str = '';
foreach($array as $key => $item){
$str .= str_pad($key, $maxLength, ' ', STR_PAD_RIGHT) . $item . '\n'; //add padding to the right hand side of the word with spaces
}
file_put_contents('path/to/file', $str);
This probably isn't the best solution but you could probably make it more efficient.
Update
I revised the functionality, and the below will work with a string (array key) of any length.
$longest = 0;
// find the longest string.
foreach ($array as $key => $val) {
$c = strlen($key);
$longest = ($c > $longest) ? $c : $longest;
}
$distance = 5;
$str = '';
// now loop through and apply the appropriate space
foreach ($array as $key => $val) {
$c = strlen($key);
$space = $distance + ($longest - $c);
$str .= $key . str_repeat(" ", $space) . $val . "\n";
}
echo $str;
Example
I don't understand why you'd want to do something like this, but this will do as you desire:
$str = '';
foreach($array as $key => $item){
$str .= $key . "\t" .$item ."\n";
}
file_put_contents('path/to/file', $str);
Example
You'd obviously have to test the file_put_contents() to ensure it succeeded, but I'll leave that to you.
You'd just have to change the ammount of tabs (\t) if you run into any long strings. In your case, it'd probably be best if you went with 2 (\t\t).
$Offer is your array
$file = 'people.txt';
$content = '';
foreach ($Offer as $key => $value) {
$content .= $key.'='.$value;
// Write the contents back to the file
file_put_contents($file, $current);
}
Related
How do i explode a following string
$str = "ProductId=123, Name=Ancient Roots, Modern Pursuits, Country=India, City=Bangalore, Price=3368"
Such that output array will contain
[
"ProductId" => "123",
"Name" => "Ancient Roots, Modern Pursuits",
"Country" => "India",
"City" => "Bangalore",
"Price" => "3368"
]
I tried to explode by "comma", then each element again explode by "equal to" as.
$arr = explode(",", $str);
and again
$prodarr = explode("=", $arr[0]);
$product["ProductId"] = $prodarr[1]
But facing problem when another comma is exist in value like in name "Ancient Roots, Modern Pursuits"
Your structure is very weak for breaking. But you can still try to parse it.
First explode on =. You will have next key and current value.
Then loop these and explode on , and select last element for next key and all previous parts as value (sample):
<?php
$str = "ProductId=123, Name=Ancient Roots, Modern Pursuits, Country=India, City=Bangalore, Price=3368";
$chunks = explode('=', $str);
$keys = [];
$values = [];
foreach ($chunks as $i => $chunk) {
$parts = explode(',', $chunk);
if ($i != count($chunks) - 1) {
$keys[] = trim(array_pop($parts));
}
if ($i != 0) {
$values[] = implode(',', $parts);
}
}
var_dump(array_combine($keys, $values));
I played a little bit around. I used preg_match_all() to extract the Patterns which contain characters that are no , and no = followed by a = followed by characters that are no = followed by a , or end of line. here is the result:
$result = array();
preg_match_all('/([^=,]+=[^=]+)(,|$)/', $string, $matches);
foreach($matches[1] as $data){
$data = explode('=', $data);
$result[trim($data[0])] = trim($data[1]);
}
$result = json_encode($result);
The result is:
{"ProductId":"123","Name":"Ancient Roots, Modern Pursuits","Country":"India","City":"Bangalore"}
Try something like this
<?php
$str = "ProductId=123, Name=Ancient Roots, Modern Pursuits, Country=India, City=Bangalore, Price=3368";
$str_arr = explode(",", $str);
$json_array = array();
for ($i = 0; $i < sizeof($str_arr); $i++)
{
if (isset($str_arr[$i + 1]))
{
if (strpos($str_arr[$i + 1], '=') !== false)
{
$prod = explode("=", $str_arr[$i]);
$json_array["" . $prod[0] . ""] = "" . $prod[1] . "";
}
else
{
$textAppend = "," . $str_arr[$i + 1];
$prod = explode("=", $str_arr[$i]);
$json_array["" . $prod[0] . ""] = "" . $prod[1] . "" . $textAppend . "";
$i++;
}
}
else
{
$prod = explode("=", $str_arr[$i]);
$json_array["" . $prod[0] . ""] = "" . $prod[1] . "";
}
}
var_dump($json_array);
?>
I have a text file
(0:00)
text1
text2
(0:30)
text text text text text
..................
the result should be like this
array("(0:00)"=>"text1 text2","(0:30)"=>"text text text text text")
my code
$key = array();
$val = array();
$out = array();
$file = file('1.txt');
foreach($file as $line) {
$line = trim($line);
if (preg_match("/(\d{0,2}:\d\d)/",$line,$match)){
$key[]=$match;
}else{
$val[]=$match;
}
$out=array_merge($key,$val);
}
echo '<pre>';
print_r($out);
tell me, how to fix it?
Try this:
$n = preg_match_all('/\((\d{0,2}:\d\d)\)([\s+]*?)([^\(]*)/mi', $file, $matches);
$out = array();
for ($i = 0; $i < count($matches[1]); ++$i)
{
// for removing newline characters:
$out[$matches[1][$i]] = trim(preg_replace('/\s\s+/', ' ', $matches[3][$i]));
}
var_dump($out);
At first i tried it with the way you were going, but using one regex for both seemed to be much easier.
It gave me following result:
array(2) {
["0:00"]=>
string(11) "text1 text2"
["0:30"]=>
string(24) "text text text text text"
}
You can loop the array looking for the first key, and then add all occurences to this key until you find next.
Also, your code had several logical errors:
$key[]=$match; - $match is an array, you should use the first occurence
$val[]=$match; - $match is empty in this case (match wasn't found), you should use the $line
Corrected code:
$out = array();
$key = "";
$file = file('aaa.txt');
foreach($file as $line) {
$line = trim($line);
if(empty($line)) continue;
if (preg_match("/(\d{0,2}:\d\d)/",$line,$match)){
$key = $match[0];
continue;
}
if(!empty($key)){
$out[$key] = $line;
}
}
echo '<pre>';
print_r($out);
$text = file_get_contents('1.txt');
preg_match_all("~\(\d{1,2}:\d{1,2}\)~", $text, $keys);
$values = array_values(preg_grep("~.+~", preg_split("~\(\d{1,2}:\d{1,2}\)~", $text)));
$final = [];
for ($n = 0; $n < count($keys[0]); $n++) {
$final[$keys[0][$n]] = $values[$n];
}
print_r($final);
Locked. There are disputes about this question’s content being resolved at this time. It is not currently accepting new answers or interactions.
I am trying to write a simple program which takes every 4th letter (not character) in a string (not counting spaces) and changes the case to it's opposite (If it's in lower, change it to upper or vice versa).
What I have so far:
echo preg_replace_callback('/.{5}/', function ($matches){
return ucfirst($matches[0]);
}, $strInput);
Expected Result: "The sky is blue" should output "The Sky iS bluE"
$str = 'The sky is blue';
$strArrWithSpace = str_split ($str);
$strWithoutSpace = str_replace(" ", "", $str);
$strArrWithoutSpace = str_split ($strWithoutSpace);
$updatedStringWithoutSpace = '';
$blankPositions = array();
$j = 0;
foreach ($strArrWithSpace as $key => $char) {
if (empty(trim($char))) {
$blankPositions[] = $key - $j;
$j++;
}
}
foreach ($strArrWithoutSpace as $key => $char) {
if (($key +1) % 4 === 0) {
$updatedStringWithoutSpace .= strtoupper($char);
} else {
$updatedStringWithoutSpace .= $char;
}
}
$arrWithoutSpace = str_split($updatedStringWithoutSpace);
$finalString = '';
foreach ($arrWithoutSpace as $key => $char) {
if (in_array($key, $blankPositions)) {
$finalString .= ' ' . $char;
} else {
$finalString .= $char;
}
}
echo $finalString;
Try this:
$newStr = '';
foreach(str_split($str) as $index => $char) {
$newStr .= ($index % 2) ? strtolower($char) : strtoupper($char);
}
it capitalize every 2nd character of string
<?php
$str = "The sky is blue";
$str = str_split($str);
$nth = 4; // the nth letter you want to replace
$cnt = 0;
for ($i = 0; $i < count($str); $i++) {
if($str[$i]!=" " && $cnt!=$nth)
$cnt++;
if($cnt==$nth)
{
$cnt=0;
$str[$i] = ctype_upper($str[$i])?strtolower($str[$i]):strtoupper($str[$i]);
}
}
echo implode($str);
?>
This code satisfies all of your conditions.
Edit:
I would have used
$str = str_replace(" ","",$str);
to ignore the whitespaces in the string. But as you want them in the output as it is, so had to apply the above logic.
Input Format is
6
4 5 1 9 8 7
Where first line gives the length of the array or the number of character
Required Output
array{4,5,1,9,8,7}
<?php
$fp = fopen("C://wamp//www//phptut////Insertion Sort//stdin.txt", "r");
$m = (int) fgets($fp);
var_dump($m);
$arr = array();
for ($i=0; $i<$m; $i++) {
fscanf($fp, "%d", $arr[$i]);
}
//var_dump($arr);
foreach($arr as $value) {
print $value;
}
?>
$fp = fopen("your file loc", "r");
fscanf($fp, "%d", $m);
$ar= fgets($fp);
$arr = explode(" ", $ar);
// here this explode and implode is done because here whatever you want to do with your array ..do it
$value = implode(" ", $arr);
print $value;
I need to write an array to a .csv file in PHP.
Example array:
$array = array(
"name" => "John",
"surname" => "Doe",
"email" => "nowhere#nowhere.com"
);
By using implode(",", $array), I get a result like this:
John,Doe,nowhere#nowhere.com
However, I need to also write the key of each element to the file.
The desired output is this:
name:John,surname:Doe,email:nowhere#nowhere.com
How would I achieve this?
Try this code:
$out = $sep = '';
foreach( $array as $key => $value ) {
$out .= $sep . $key . ':' . $value;
$sep = ',';
}
$csv = "";
foreach($array as $key => $data)
{
// be sure to add " in your csv
$csv .= '"'.$key.':'.$data.'",';
}
// and add a new line at the end
$csv .= "\n";
echo $csv;
The answers above outputs a trailing comma at the end. To correct this, I use the following function:
$array = array(
"name" => "John",
"surname" => "Doe",
"email" => "nowhere#nowhere.com"
);
function implodeKV($glueKV, $gluePair, $KVarray){
$t = array();
foreach($KVarray as $key=>$val) {
$t[] = $key . $glueKV . $val;
}
return implode($gluePair, $t);
}
echo implodeKV( ':' , ',' , $array);
// outputs name:John,surname:Doe,email:nowhere#nowhere.com
http://phpassist.com/2dde2#2
If you're using PHP 5.3+, then an anonymous function can make your code a lot cleaner, though a simple for loop has the best performance. (Using array_walk comes close though!)
I ran some tests with a few different approaches (using PHP 5.4.33):
function makeArray(&$a) {
$a = array();
for($i = 0; $i < 100000; $i++) {
$a[rand()] = rand();
}
return $a;
}
makeArray($array);
$before = microtime(true);
$result = implode(
",",
array_map(
function($k, $v) {
return "$k:$v";
},
array_keys($array),
$array
)
);
$after = microtime(true);
$dur = $after - $before;
echo "Array Map w/ anonymous function: {$dur}s<br>";
makeArray($array);
$before = microtime(true);
function kv_func($k, $v) {
return "$k:$v";
}
$result = implode(
",",
array_map(
"kv_func",
array_keys($array),
$array
)
);
$after = microtime(true);
$dur = $after - $before;
echo "Array Map w/ function: {$dur}s<br>";
makeArray($array);
$before = microtime(true);
array_walk(
$array,
function(&$v, $k) {
$v = "$k:$v";
}
);
$result = implode(
",",
$array
);
$after = microtime(true);
$dur = $after - $before;
echo "Array Walk w/ anonymous function: {$dur}s<br>";
makeArray($array);
$before = microtime(true);
$ff = true;
$sep = ",";
$out = "";
foreach($array as $key => $val) {
if($ff) $ff = false;
else $out .= $sep;
$out .= "$key:$val";
}
$after = microtime(true);
$dur = $after - $before;
echo "Foreach loop w/ loop flag: {$dur}s<br>";
makeArray($array);
$before = microtime(true);
$out = "";
foreach($array as $key => $val) {
$out .= "$key:$val,";
}
$out = substr($out, 0, -1);
$after = microtime(true);
$dur = $after - $before;
echo "Foreach loop + substr: {$dur}s<br>";
Results:
Array Map w/ anonymous function: 0.13117909431458s
Array Map w/ function: 0.13743591308594s // slower than anonymous
Array Walk w/ anonymous function: 0.065797805786133s // close second
Foreach loop w/ loop flag: 0.042901992797852s // fastest
Foreach loop + substr: 0.043946027755737s // comparable to the above
And just for kicks, I tried the for loop without correcting for the trailing comma. It didn't really have any impact:
Foreach loop w/ trailing comma: 0.044748067855835s
<?php
$array = array(
"name" => "John",
"surname" => "Doe",
"email" => "nowhere#nowhere.com"
);
foreach( $array as $key=>$data ) {
$output .= $comma . $key . ':' . $data;
$comma = ',';
}
echo $output;
?>