18

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?

2
  • 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 Commented Sep 6, 2012 at 22:04
  • a 5-second google search turned up this: php.net/manual/en/function.join.php In the comments, you'll find a recursive join snippet that should suit your needs. Commented Sep 6, 2012 at 22:04

9 Answers 9

24

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);
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for this, I'm going to study how this works as so many of my questions have been answered with "array_map."
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

5 Comments

Great answer! but is there any way to avoid Notice: Undefined offset: 0 in... for associative arrays? Thanks
Yes! Instead of is_array($arr[$i]) write @is_array($arr[$i]) I changed in code already.
Thanks, but what does the @ do? I tried googling, but I didn't find the documentation... Thanks
Thanks. Another solution which I whipped up before you told me about the @, was to convert the array into a numerical one at the beginning of the function
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;
}

Comments

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);
}

1 Comment

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.
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!

1 Comment

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

Comments

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

Comments

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

Comments

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);
}

Comments