foreach concatenate each element to next one - php

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.

Related

The string is converted to an array several times

I want to convert the string to an array.The following example.
1.Capitalize the first letter
2.The letter after ',' or '_' becomes capital
3.Strings are separated by ','
4.swap underline to ' '
$str_1 = "_ab,cb_ef,kk,uu";
$str_2 = ",cb_ef,kk,uu";
$str_3 = "cb_ef,kk,uu";
//convert to
$arr_1 = ('Ab','Cb Ef','Kk','Uu');
$arr_2 = ('Cb Ef','Kk','Uu');
$arr_3 = ('Cb Ef','Kk','Uu');
//There are my code and result .
$func = function( $str ){
$str_len = strlen( $str );
for ( $i = 0 ; $i < $str_len ; $i++ )
{
if ( $str[ $i ] == ',' && $str[ $i ] == '_' )
{
$str[ $i ] = $str[ $i ] == '_' ? ' ' : $str[ $i ] ;
if ( ord( $str[ $i +1 ] ) <= 122 && ord( $str[ $i +1 ] ) >= 97 )
{
$str[ $i ] = chr( ord( $str[ ++$i ] ) - 32 );
}
}
}
return $str;
};
var_dump(explode( ',' , $func( 'ss,adsa_sdfs' )));
//result is this
array(2) { [0]=> string(2) "ss" [1]=> string(9) "adsa_sdfs" }
Try this
function conv( $str ) {
$res = [];
$arr = explode( ',' , $str );
foreach ( $arr as $key => $value ) {
$res[] = ucwords( str_replace( '_' , ' ' , $value ) );
}
return $res;
}
var_dump( conv( 'ss,adsa_sdfs' ) );
Response:
array(2) { [0]=> string(2) "Ss" [1]=> string(9) "Adsa Sdfs" }
The demo code with your test cases:
<?php
function upper($s, $sep)
{
// upper the char separated by $sep
$a = explode($sep, $s);
$a = array_map('ucfirst', $a);
return join($sep, $a);
}
function test($s)
{
// upper the chars separated by '_'
$s = upper($s, '_');
// upper the chars separated by ','
$s = upper($s, ',');
// change all '_' to ' ' and upper the chars
$s = str_replace('_', ' ', $s);
$s = upper($s, ' ');
// trim unused chars
$s = trim($s, ' ,');
return explode( ',', $s);
}
$tests = [
"_ab,cb_ef,kk,uu" => ['Ab','Cb Ef','Kk','Uu'],
",cb_ef,kk,uu" => ['Cb Ef','Kk','Uu'],
"cb_ef,kk,uu" => ['Cb Ef','Kk','Uu'],
"ss,adsa_sdfs" => ['Ss', 'Adsa Sdfs'],
];
foreach ($tests as $s=>$a) {
$out = test($s);
if ($out === $a) {
echo "OK! $s = " . json_encode($a) . PHP_EOL;
} else {
echo "WRONG! $s is " . json_encode($out) . PHP_EOL;
}
}
Output:
OK! _ab,cb_ef,kk,uu = ["Ab","Cb Ef","Kk","Uu"]
OK! ,cb_ef,kk,uu = ["Cb Ef","Kk","Uu"]
OK! cb_ef,kk,uu = ["Cb Ef","Kk","Uu"]
OK! ss,adsa_sdfs = ["Ss","Adsa Sdfs"]
Write this
<?php
$str_1 = "_ab,cb_ef,kk,uu";
$str_2 = ",cb_ef,kk,uu";
$str_3 = "cb_ef,kk,uu";
function convert_to($arr){
$arr = str_replace('_', ' ', $arr);
$arr_1 = explode(",",$arr);
$new_array = array_map('trim', $arr_1);
$new_array = array_map('ucwords', $arr_1); // first letter after word capitalize
$new_array = array_filter($new_array, 'strlen'); // remove empty item
$new_array = array_values($new_array); // arrange and shift after removing empty item
return $new_array;
}
$arr_1 = convert_to($str_1);
$arr_2 = convert_to($str_2);
$arr_3 = convert_to($str_3);
var_dump($arr_1);
var_dump($arr_2);
var_dump($arr_3);
Output :
array(4) {
[0]=>
string(3) " Ab"
[1]=>
string(5) "Cb Ef"
[2]=>
string(2) "Kk"
[3]=>
string(2) "Uu"
}
array(3) {
[0]=>
string(5) "Cb Ef"
[1]=>
string(2) "Kk"
[2]=>
string(2) "Uu"
}
array(3) {
[0]=>
string(5) "Cb Ef"
[1]=>
string(2) "Kk"
[2]=>
string(2) "Uu"
}
You could use PHP's built-in functions for this kind of situation:
function processString($param){
$explode = explode(',', $param);
$replace = str_replace('_', ' ', $explode);
$replace = array_map('trim', $replace);
$ucfirst = array_map('ucwords', $replace);
return $ucfirst;
}
The explanation is:
First we convert the string to array based on comma separation using explode() method.
Next, we need to convert underscore into space using str_replace() method.
I noticed in your example that string with space (previously underscore) in it is stripped. This need to be implemented using trim(). Since the string already converted into array, we use array_map() method to process trim for all array values.
Finally, convert every word to uppercase. Fortunately, PHP already have the method: ucwords(). Just need to array_map() it.
This is how you test the code:
$str_1 = "_ab,cb_ef,kk,uu";
$str_2 = ",cb_ef,kk,uu";
$str_3 = "cb_ef,kk,uu";
print_r(processString($str_1));
print_r(processString($str_2));
print_r(processString($str_3));
Try the following code:
<?php
function ConvertToArr($str)
{
$result = array();
$temp_arr1 = explode(",", $str);
for ($count1 = 0; $count1 < count($temp_arr1); $count1++) {
$temp_results = array();
$temp_arr2 = explode("_", $temp_arr1[$count1]);
for ($count2 = 0; $count2 < count($temp_arr2); $count2++) {
$temp_str = ucfirst($temp_arr2[$count2]);
if ($temp_str != "")
$temp_results []= $temp_str;
}
$temp_results = implode(" ", $temp_results);
if (trim($temp_results) != "")
$result []= $temp_results;
}
return $result;
}
$str_1 = "_ab,cb_ef,kk,uu";
$str_2 = ",cb_ef,kk,uu";
$str_3 = "cb_ef,kk,uu";
print_r(ConvertToArr($str_1));
print_r(ConvertToArr($str_2));
print_r(ConvertToArr($str_3));
?>
It produces the following output:
Array
(
[0] => Ab
[1] => Cb Ef
[2] => Kk
[3] => Uu
)
Array
(
[0] => Cb Ef
[1] => Kk
[2] => Uu
)
Array
(
[0] => Cb Ef
[1] => Kk
[2] => Uu
)

PHP for loop stops too early

I have a loop which increments the limit of the content which is showing on a website (json content).
The problem is that the loop stops at 50. The links that are generated with the incrementation are working fine when I'm calling them in the browser. The content is shown.
But I store only the content of the first 50 and then it stops.
public static function getAllCustomers() {
$rest = Rest::getInstance();
$spaces = self::getSpaces();
$customers = array();
$path = SpacePath::buildPath();
for ($i = 0;
; $i += Paths::$MAX_CONTENT_LENGTH) {
$temp = $path . '?start=' . $i . '&limit=50';
$content = Helper::toArray($temp);
print_r($temp);
// print_r(empty($content['results']));
if (!empty($content['results'])) {
foreach ($content ['results'] as $space) {
if (!preg_match('|^(.*?)-([0-9]+)|i', $space ['name'], $matches)) {
continue;
}
$customer = (object) array(
'name' => $matches [0],
'ident' => $matches [1],
'id' => $matches [2],
'space_key' => $space ['key'],
'options' => array()
);
$customers [] = $customer;
}
break;
}
}
print_r($customers);
return $customers;
}
Here, let me reformat your code so you can see what relates to what...
public static function getAllCustomers()
{
$rest = Rest::getInstance();
$spaces = self::getSpaces();
$customers = array();
$path = SpacePath::buildPath();
for ($i = 0; ; $i += Paths::$MAX_CONTENT_LENGTH)
{
$temp = $path . '?start=' . $i . '&limit=50';
$content = Helper::toArray($temp);
print_r($temp);
//print_r(empty($content['results']));
if (!empty($content['results']))
{
foreach ($content ['results'] as $space)
{
if (!preg_match('|^(.*?)-([0-9]+)|i', $space ['name'], $matches))
{
continue;
}
$customer = (object) array('name' => $matches [0]
,'ident' => $matches [1]
,'id' => $matches [2]
,'space_key' => $space ['key']
,'options' => array()
);
$customers [] = $customer;
}
break; // oops
}
}
print_r($customers);
return $customers;
}
You'll notice I added a comment to your break statement. ;)

How to loop over a string's characterss?

Basically, I have an array of strings, and I want to check if each character in each string is in a predefined $source string. Here is how I think it should be done:
$source = "abcdef";
foreach($array as $key => $value) {
foreach(char in $value) {
if(char is not in source)
unset($array[$key]); //remove the value from array
}
}
If this is a correct logic, how to implement the foreach and the if parts?
You could try this:
$array = array('1' => 'cab', '2' => 'bad', '3' => 'zoo');
$source = "abcdef";
foreach($array as $key => $value) {
$split = str_split($value);
foreach($split as $char){
$pos = strrpos($source, $char);
if ($pos === false) {
unset($array[$key]);
break;
}
}
}
Result:
array(2) {
[1]=>
string(3) "cab"
[2]=>
string(3) "bad"
}
DEMO: http://codepad.org/fU99Gdtd
Try this code:
$source = "abcdef";
foreach($array as $key => $value) {
$ichr = strlen($value) - 1;
// traverses each character in string
for($i=0; $i<$ichr; $i++) {
if(stristr($value{$i}) === false) {
unset($array[$key]);
break;
}
}
}
$array = array("abc","defg","asd","ade","de","fe");
$source = "abcde";
foreach ($array as $key => $string){
for($i=0;$i<strlen($string);$i++){
if(strpos($source, $string[$i])===false){
unset($array[$key]);
}
}
}
Now the array looks like
array(3) {
[0]=>
string(3) "abc"
[3]=>
string(3) "ade"
[4]=>
string(2) "de"
}
As I understand you want to filter ( remove ) the characters, that are not defined in the $source variable. By Mark Baker comments, this is what you need:
$source = str_split ( "abdef" ); //defined characters
$target = str_split ( "atyutyu" ); //string to be filtered
$result = array_intersect ( $target, $source );
echo implode( $result ); // output will be only "a"
And full example:
$source = str_split ( "abdef" );
$txts = array ( "alfa", "bravo", "charlie", "delta" );
function filter ( $toBeChecked, $against )
{
$target = str_split ( $toBeChecked );
return implode ( array_intersect ( $target, $against ) );
}
foreach ( $txts as &$value )
{
$value = filter ( $value, $source );
}
foreach ( $txts as $value )
{
echo $value . ", ";
}
//output afa, ba, ae, ae
$array = array(
'abacab',
'baccarat',
'bejazzle',
'barcode',
'zyx',
);
$source = "abcde";
$sourceArray = str_split($source);
foreach($array as $value) {
$matches = array_intersect($sourceArray, str_split($value));
echo $value;
if (count($matches) == 0) {
echo ' contains none of the characters ', $source, PHP_EOL;
} elseif (count($matches) == count($sourceArray)) {
echo ' contains all of the characters ', $source, PHP_EOL;
} else {
echo ' contains ', count($matches), ' of the characters ', $source, ' (', implode($matches), ')', PHP_EOL;
}
}
gives
abacab contains 3 of the characters abcde (abc)
baccarat contains 3 of the characters abcde (abc)
bejazzle contains 3 of the characters abcde (abe)
barcode contains all of the characters abcde
zyx contains none of the characters abcde

PHP combine arrays on similar elements

I have some data in this format:
even--heaped<br />
even--trees<br />
hardrocks-cocked<br />
pebble-temple<br />
heaped-feast<br />
trees-feast<br />
and I want to end up with an output so that all lines with the same words get added to each other with no repeats.
even--heaped--trees--feast<br />
hardrocks--cocked<br />
pebbles-temple<br />
i tried a loop going through both arrays but its not the exact result I want. for an array $thing:
Array ( [0] => even--heaped [1] => even--trees [2] => hardrocks--cocked [3] => pebbles--temple [4] => heaped--feast [5] => trees--feast )
for ($i=0;$i<count($thing);$i++){
for ($j=$i+1;$j<count($thing);$j++){
$first = explode("--",$thing[$i]);
$second = explode("--",$thing[$j]);
$merge = array_merge($first,$second);
$unique = array_unique($merge);
if (count($unique)==3){
$fix = implode("--",$unique);
$out[$i] = $thing[$i]."--".$thing[$j];
}
}
}
print_r($out);
but the result is:
Array ( [0] => even--heaped--heaped--feast [1] => even--trees--trees--feast [4] => heaped--feast--trees--feast )
which is not what i want. Any suggestions (sorry about the terrible variable names).
This might help you:
$in = array(
"even--heaped",
"even--trees",
"hardrocks--cocked",
"pebbles--temple",
"heaped--feast",
"trees--feast"
);
$clusters = array();
foreach( $in as $item ) {
$words = explode("--", $item);
// check if there exists a word in an existing cluster...
$check = false;
foreach($clusters as $k => $cluster) {
foreach($words as $word) {
if( in_array($word, $cluster) ) {
// add the words to this cluster
$clusters[$k] = array_unique( array_merge($cluster, $words) );
$check = true;
break;
}
}
}
if( !$check ) {
// create a new cluster
$clusters[] = $words;
}
}
// merge back
$out = array();
foreach( $clusters as $cluster ) {
$out[] = implode("--", $cluster);
}
pr($out);
Try this code:
<?php
$data = array ("1--2", "3--1", "4--5", "2--6");
$n = count($data);
$elements = array();
for ($i = 0; $i < $n; ++$i)
{
$split = explode("--", $data[$i]);
$word_num = NULL;
foreach($split as $word_key => $word)
{
foreach($elements as $key => $element)
{
if(isset($element[$word]))
{
$word_num = $key;
unset($split[$word_key]);
}
}
}
if(is_null($word_num))
{
$elements[] = array();
$word_num = count($elements) - 1;
}
foreach($split as $word_key => $word)
{
$elements[$word_num][$word] = 1;
}
}
//combine $elements into words
foreach($elements as $key => $value)
{
$words = array_keys($value);
$elements[$key] = implode("--", $words);
}
var_dump($elements);
It uses $elements as an array of hashes to store the individual unique words as keys. Then combines the keys to create appropriate words.
Prints this:
array(2) {
[0]=>
string(10) "1--2--3--6"
[1]=>
string(4) "4--5"
}
Here is a solution with a simple control flow.
<?php
$things = array('even--heaped', 'even--trees', 'hardrocks--cocked',
'pebble--temple', 'heaped--feast' ,'trees--feast');
foreach($things as $thing) {
$str = explode('--', $thing);
$first = $str[0];
$second = $str[1];
$i = '0';
while(true) {
if(!isset($a[$i])) {
$a[$i] = array();
array_push($a[$i], $first);
array_push($a[$i], $second);
break;
} else if(in_array($first, $a[$i]) && !in_array($second, $a[$i])) {
array_push($a[$i], $second);
break;
} else if(!in_array($first, $a[$i]) && in_array($second, $a[$i])) {
array_push($a[$i], $first);
break;
} else if(in_array($first, $a[$i]) && in_array($second, $a[$i])) {
break;
}
$i++;
}
}
print_r($a);
?>
It seems you have already selected user4035's answer as best.
But i feel this one is optimized(Please correct me if i am wrong): eval.in
Code:
$array = Array ( 'even--heaped' , 'even--trees' ,'hardrocks--cocked' , 'pebbles--temple' , 'heaped--feast' , 'trees--feast' );
print "Input: ";
print_r($array);
for($j=0;$j < count($array);$j++){
$len = count($array);
for($i=$j+1;$i < $len;$i++){
$tmp_array = explode("--", $array[$i]);
$pos1 = strpos($array[$j], $tmp_array[0]);
$pos2 = strpos($array[$j], $tmp_array[1]);
if (!($pos1 === false) && $pos2 === false){
$array[$j] = $array[$j] . '--'.$tmp_array[1];unset($array[$i]);
}elseif(!($pos2 === false) && $pos1 === false){
$array[$j] = $array[$j] . '--'.$tmp_array[0];unset($array[$i]);
}elseif(!($pos2 === false) && !($pos1 === false)){
unset($array[$i]);
}
}
$array = array_values($array);
}
print "\nOutput: ";
print_r($array);

Implode with array with keys in PHP

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;
?>

Categories