I have some array that look like this
$links =array('proizvodi','pokloni', 'kuhinja');
I need to create another array that will look like this
$linksNew =array('proizvodi/','proizvodi/pokloni/', 'proizvodi/pokloni/kuhinja/');
Txanks in advance
This would be a primitive approach:
<?php
$input = ['proizvodi','pokloni', 'kuhinja'];
$output = [];
$previous = '';
foreach ($input as $entry) {
$output[] = $previous . $entry . '/';
$previous = end($output);
}
var_dump($output);
This is a version some might consider a bit more elegant:
<?php
$input = ['proizvodi','pokloni', 'kuhinja'];
$output = [];
$previous = '';
array_walk($input, function($entry) use (&$previous, &$output) {
$output[] = $previous . $entry . '/';
$previous = end($output);
});
var_dump($output);
The output of both versions obviously is:
array(3) {
[0]=>
string(10) "proizvodi/"
[1]=>
string(18) "proizvodi/pokloni/"
[2]=>
string(26) "proizvodi/pokloni/kuhinja/"
}
This would be a approach without a for or foreach loop
$links = array('proizvodi','pokloni', 'kuhinja');
$newLinks = array_map(function($i) use ($links) {
return implode(array_slice($links, 0, $i), '/') . '/';
}, range(1, count($links)));
Trying to think of a slicker way, but this works:
for($i=0; $i<count($links); $i++) {
$linksNew[] = implode('/', array_slice($links, $i)) . '/';
}
$linksNew = array_reverse($linksNew);
Related
I would like to concatenate each element of array to next one. I want the output array to be:
Array
(
[0] => test
[1] => test/test2
[2] => test/test2/test3
[3] => test/test2/test3/test4
)
I tried the following way which concatenates each string to itself:
$url = preg_split("/[\s\/]+/", "test/test2/test3/test4");
foreach ($url as $dir) {
$dir .= $dir;
}
Any help appreciated.
Maybe another way
<?php
$data = array( 'test', 'test2', 'test3', 'test4' );
for( $i = 0; $i < count( $data ); $i++ )
{
if( $i != 0 )
{
$new[ $i ] = $new[ $i - 1 ] .'/'. $data[ $i ];
}
else
{
$new[ $i ] = $data[ $i ];
}
}
var_dump( $new );
Output
array(4) {
[0]=>
string(4) "test"
[1]=>
string(10) "test/test2"
[2]=>
string(16) "test/test2/test3"
[3]=>
string(22) "test/test2/test3/test4"
}
You should obtain the result you need in $my_array
$url = explode("/", "test/test2/test3/test4");
$str ='';
foreach($url as $key => $value){
if ( $str == '') {
$str .= $str;
} else {
$str .= '/'.$str;
}
$my_array[$key] = $str ;
echo $str . '<br />';
}
var_dump($my_array);
$url = preg_split("/[\s\/]+/", "test/test2/test3/test4");
$arr = array();
$str = '';
foreach ($url as $key => $dir) {
if ($key !== 0) {
$str .= '/' . $dir;
} else {
$str .= $dir;
}
$arr[] = $str;
}
On each iteration concate a string with new value and add it as a separate value for your output array.
Here's a quick way. For simple splitting just use explode():
$url = explode("/", "test/test2/test3/test4");
foreach($url as $value) {
$temp[] = $value;
$result[] = implode("/", $temp);
}
Each time through the loop, add the current value to a temporary array and implode it into the next element of the result.
I have String array like below format
Array(
"Courses",
"Courses/PHP",
"Courses/PHP/Array",
"Courses/PHP/Functions",
"Courses/JAVA",
"Courses/JAVA/String");
I need result like below
Courses
- PHP
- Array
- Functions
- JAVA
- Strings
I used substr option to get result.
for($i=0;$i<count($outArray);$i++)
{
$strp = strrpos($outArray[$i], '/')+1;
$result[] = substr($outArray[$i], $strp);
}
But I didn't get result like tree structure.
How do I get result like tree structure.
Something like that?
$a = array(
"Courses",
"Courses/PHP",
"Courses/PHP/Array",
"Courses/PHP/Functions",
"Courses/JAVA",
"Courses/JAVA/String");
$result = array();
foreach($a as $item){
$itemparts = explode("/", $item);
$last = &$result;
for($i=0; $i < count($itemparts); $i++){
$part = $itemparts[$i];
if($i+1 < count($itemparts))
$last = &$last[$part];
else
$last[$part] = array();
}
}
var_dump($result);
The result is:
array(1) {
["Courses"]=>
array(2) {
["PHP"]=>
array(2) {
["Array"]=>
array(0) {
}
["Functions"]=>
array(0) {
}
}
["JAVA"]=>
&array(1) {
["String"]=>
array(0) {
}
}
}
}
How about this one:
<?php
$outArray = Array(
"Courses",
"Courses/PHP",
"Courses/PHP/Array",
"Courses/PHP/Functions",
"Courses/JAVA",
"Courses/JAVA/String");
echo "-" . $outArray[0] . "<br/>";
for($i=0;$i<count($outArray) - 1;$i++)
{
create_tree($outArray[$i],$outArray[$i+1]);
}
function create_tree($prev, $arr)
{
$path1 = explode("/", $prev);
$path2 = explode("/", $arr);
if (count($path1) > count($path2))
echo str_repeat(" ",count($path1) - 1) . "-" . end($path2);
else
echo str_repeat(" ",count($path2) - 1) . "-" . end($path2);
echo $outArray[$i] . "<br/>";
}
Outputs:
-Courses
-PHP
-Array
-Functions
-JAVA
-Strings
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;
?>
I want to combine strings in PHP. My script creates every possible combination like below.
$part1 = array('','d','n','s','g');
$part2 = array('a','e','o','oo');
$part3 = array('m','n','s','d','l','t','g','j','p');
$part4 = array('g','p','l','');
$part5 = array('g','p','l');
$part6 = array('a','e','o');
$part7 = array('d','l','r','');
$names = array();
foreach ($part1 as $letter1) {
foreach ($part2 as $letter2) {
foreach ($part3 as $letter3) {
foreach ($part4 as $letter4) {
foreach ($part5 as $letter5) {
foreach ($part6 as $letter6) {
foreach ($part7 as $letter7) {
$names[] = $letter1 . $letter2 . $letter3 . $letter4 . $letter5 . $letter6 . $letter7;
}
}
}
}
}
}
}
But I am not happy with my solution. I is quick and dirty code. Is there a solution wich works with a flexible number of part arrays, so I can extend the script by e.g. $part8 easiely? (without changing the loop construction)
Recursive one:
function buildNames( $parts, $chars = ''){
// Nothing to do, shouldn't happen
if( !count( $parts)){
return array();
}
$names = array();
$part = array_shift( $parts);
// Max level, we can build final names from characters
if( !count( $parts)){
foreach( $part as $char){
$names[] = $chars . $char;
}
return $names;
}
// "We need to go deeper" and build one more level with remembered chars so far
foreach( $part as $char){
$names = array_merge( $names, buildNames( $parts, $chars . $char));
}
return $names;
}
$parts = array( $part1, $part2, $part3, $part4, $part5, $part6, $part7);
$names = buildNames( $parts);
From head, from scratch, comment if something, but idea should be good
You could reduce this problem to six cartesian products:
cartesianProduct($part1,
cartesianProduct($part2,
cartesianProduct($part3,
cartesianProduct($part4,
cartesianProduct($part5,
cartesianProduct($part6, $part7))))));
function cartesianProduct($p1, $p2) {
$ret = array();
foreach($p1 as $l1)
foreach($p2 as $l2)
$ret[] = $l1 . $l2;
return $ret;
}
I'm trying to create an array while parsing a string separated with dots
$string = "foo.bar.baz";
$value = 5
to
$arr['foo']['bar']['baz'] = 5;
I parsed the keys with
$keys = explode(".",$string);
How could I do this?
You can do:
$keys = explode(".",$string);
$last = array_pop($keys);
$array = array();
$current = &$array;
foreach($keys as $key) {
$current[$key] = array();
$current = &$current[$key];
}
$current[$last] = $value;
DEMO
You can easily make a function out if this, passing the string and the value as parameter and returning the array.
You can try following solution:
function arrayByString($path, $value) {
$keys = array_reverse(explode(".",$path));
foreach ( $keys as $key ) {
$value = array($key => $value);
}
return $value;
}
$result = arrayByString("foo.bar.baz", 5);
/*
array(1) {
["foo"]=>
array(1) {
["bar"]=>
array(1) {
["baz"]=>
int(5)
}
}
}
*/
This is somehow related to the question you can find an answer to, here:
PHP One level deeper in array each loop made
You would just have to change the code a little bit:
$a = explode('.', "foo.bar.baz");
$b = array();
$c =& $b;
foreach ($a as $k) {
$c[$k] = array();
$c =& $c[$k];
}
$c = 5;
print_r($b);