16

I am trying to convert a multidimensional array into a string with a particular format.

function convert_multi_array($array) {
    foreach($array as $value) {
        if(count($value) > 1) {
            $array = implode("~", $value);
        }
        $array = implode("&", $value);
    }
    print_r($array);
}
$arr = array(array("blue", "red", "green"), array("one", "three", "twenty"));
convert_multi_array($arr);

Should Output: blue~red~green&one~three~twenty ... and so on for more sub-arrays.

Let me just say that I have not been able to produce any code that is remotely close to the results I want. After two hours, this is pretty much the best I can get. I don't know why the implodes are acting differently than they usually do for strings or maybe I'm just not looking at this right. Are you able to use implode for arrays values?

  • Looping over a multidimensional array of any kind normally requires two loops nested. Loop over first array, then loop over second array, when finished, move to next array, loop over that. Etc – Tony The Lion Sep 06 '12 at 22:04
  • a 5-second google search turned up this: http://php.net/manual/en/function.join.php In the comments, you'll find a recursive join snippet that should suit your needs. – Shmiddty Sep 06 '12 at 22:04

10 Answers10

22

You are overwriting $array, which contains the original array. But in a foreach a copy of $array is being worked on, so you are basically just assigning a new variable.

What you should do is iterate through the child arrays and "convert" them to strings, then implode the result.

function convert_multi_array($array) {
  $out = implode("&",array_map(function($a) {return implode("~",$a);},$array));
  print_r($out);
}
Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592
  • Thank you for this, I'm going to study how this works as so many of my questions have been answered with "array_map." –  Sep 06 '12 at 22:09
7

Look at my version. It implodes any dimension:

function implode_all($glue, $arr){            
    for ($i=0; $i<count($arr); $i++) {
        if (@is_array($arr[$i])) 
            $arr[$i] = implode_all ($glue, $arr[$i]);
    }            
    return implode($glue, $arr);
}

Here is the example:

echo implode_all(',', 
array(
1,
2,
array('31','32'),
array('4'),
array(
  array(511,512), 
  array(521,522,523,524),
  53))
);

Will print:

1,2,31,32,4,511,512,521,522,523,524,53
Jeff_Alieffson
  • 2,672
  • 29
  • 34
3

I tried a bunch of these, but non of them ticked all the boxes for me. The one that came the closes was Jeff_Alieffsons.

Here is an adjusted version, where you can chuck whatever multidimensional array into it, and then it'll return a string.

function implode_all( $glue, $arr ){
  if( is_array( $arr ) ){

    foreach( $arr as $key => &$value ){

      if( @is_array( $value ) ){
        $arr[ $key ] = implode_all( $glue, $value );
      }
    }

    return implode( $glue, $arr );
  }

  // Not array
  return $arr;
}
Zeth
  • 2,273
  • 4
  • 43
  • 91
1

Saving the imploded inner arrays to an array. Then imploding those.

(written in the spirit of your original implementation)

function convert_multi_array($arrays)
{
    $imploded = array();
    foreach($arrays as $array) {
        $imploded[] = implode('~', $array);
    }
    return implode("&", $imploded);
}
desimusxvii
  • 1,094
  • 1
  • 8
  • 10
  • Ah yes, the spirit of this. I should have just asked for help earlier, the code I posted was a scramble of mess after many hours of banging my head. –  Sep 06 '12 at 22:12
1

Here is a simple answer:

    function implode_recur ($separator, $arrayvar){
        $output = "";
         foreach ($arrayvar as $av)
         {
             if (is_array ($av))
             {
                $output .= implode_r ($separator, $av);
             }
            else
            {
                $output .= $separator.$av;
            }
            return $output;
         }
    }
    $result = implode_recur(">>",$variable);

Okay happy coding!

mega6382
  • 9,211
  • 17
  • 48
  • 69
kachmi
  • 43
  • 1
  • 10
  • Thanks for this one. I fixed some lines function implode_recur ($separator, $arrayvar){ $output = ''; foreach ($arrayvar as $av) { if (is_array ($av)) { $output .= implode_recur($separator, $av); } else { $output .= $separator.$av; } } return $output; } – Ezequiel Villarreal Aug 21 '21 at 16:43
1

May be of no interest, but i needed to report a nested array which contained errors, so i simply defined an variable and then with json_encode put this in my email. One way of converting a array to a string.

0

You also can just take the original implementation from the PHP join manual (http://php.net/manual/en/function.join.php)

function joinr($join, $value, $lvl=0)
{
    if (!is_array($join)) return joinr(array($join), $value, $lvl);
    $res = array();
    if (is_array($value)&&sizeof($value)&&is_array(current($value))) { // Is value are array of sub-arrays?
        foreach($value as $val)
            $res[] = joinr($join, $val, $lvl+1);
    }
    elseif(is_array($value)) {
        $res = $value;
    }
    else $res[] = $value;
    return join(isset($join[$lvl])?$join[$lvl]:"", $res);
}

$arr = array(array("blue", "red", "green"), array("one", "three", "twenty"));
joinr(array("&", "~"), $arr);

This is recursive, so you even can do

$arr = array(array("a", "b"), array(array("c", "d"), array("e", "f")), "g");
joinr(array("/", "-", "+"), $arr);

and you'll get

a-b/c+d-e+f/g
Mark
  • 6,033
  • 1
  • 19
  • 14
0

You can use this one line array to string code:

$output = implode(", ",array_map(function($a) { return '<a href="'.$a['slug'].'">'.$a['name'].'</a>'; }, $your_array) );

print_r($output);

Output:

Link1, Link2, Link3

Irshad Khan
  • 5,670
  • 2
  • 44
  • 39
0

If someone need a safe general function for two dimensional arrays (like a table) that can support adding keys name i think this one can be good:

function arystr($ary='',$key=false,$rowsep=PHP_EOL,$cellsep=';') { // The two dimensional array, add keys name or not, Row separator, Cell Separator
    $str='';
    if (!is_array($ary)) {
        $str=strval($ary);
    } else if (count($ary)) {
        foreach ($ary as $k=>$t) {
            $str.=($key ? $k.$cellsep : '').(is_array($t) ? implode($cellsep,$t) : $t);
            end($ary);
            if ($k !== key($ary)) $str.=$rowsep;
        }
    }
    return $str;
}
  • I use this as an Array To CSV String function

So if our input be like:

$a=array(array("blue", "red", "green"), array("one", "three", "twenty"));
echo arystr($a);

The result will be:

blue;red;green
one;three;twenty

Another example that implode keys too:

$a = array(
  'first' => array
  (
    'a' , 'b'
  ),
  'second' => array
  (
    'c','d'
  ),
  'third' => array
  (
    'e','f'
  )
);
echo arystr($a,true,'|',',');

Result :

first,a,b|second,c,d|third,e,f
MMMahdy-PAPION
  • 915
  • 10
  • 15
0

Reccursive implode:

function arrayToString($arrs,$sep=' ')
{
    if(!is_array($arrs)) return $arrs;
        
    $list=array();
    foreach($arrs as $arr)
    {
        if(is_array($arr))
        {
            $list[]=$this->arrayToString($arr,$sep);
        }
        else
        {
            $list[]=JString::trim($arr);
        }
    }
    return implode($sep,$list);
}
Stergios Zg.
  • 652
  • 6
  • 9