39

Say I have an array:

$array = Array(
  'foo' => 5,
  'bar' => 12,
  'baz' => 8
);

And I'd like to print a line of text in my view like this:

"The values are: foo (5), bar (12), baz (8)"

What I could do is this:

$list = Array();
foreach ($array as $key => $value) {
  $list[] = "$key ($value)";
}
echo 'The values are: '.implode(', ',$list);

But I feel like there should be an easier way, without having to create the $list array as an extra step. I've been trying array_map and array_walk, but no success.

So my question is: what's the best and shortest way of doing this?

2
  • I dunno of a built-in function for this. Only of var_export and var_dump but they both show it in a diff format than what you want Commented Jul 2, 2011 at 12:32
  • I suggest also to take a look at http_build_query function. It doesn't format the output the way you asked but it's very easy to implement. Commented May 29, 2017 at 11:12

7 Answers 7

45

For me the best and simplest solution is this:

$string = http_build_query($array, '', ',');

http_build_query (php.net)

Sign up to request clarification or add additional context in comments.

6 Comments

this is kind of cool, but with the encoding, you might not get what you wanted. But works well for simple cases.
With this method you cannot change the equal operator, which was requested.
Note this function URL-encodes keys and values source array.
This should be $string = urldecode ( http_build_query($array, '', ',') ) ; to get none ASCII string.
I end up with most of the array values missing in my case. build query filtered them out.
|
32

The problem with array_map is that the callback function does not accept the key as an argument. You could write your own function to fill the gap here:

function array_map_assoc( $callback , $array ){
  $r = array();
  foreach ($array as $key=>$value)
    $r[$key] = $callback($key,$value);
  return $r;
}

Now you can do that:

echo implode(',',array_map_assoc(function($k,$v){return "$k ($v)";},$array));

1 Comment

Wouldn't it produce an extra array traversal (one for array_map_assoc, another one for implode)?
10

There is a way, but it's pretty verbose (and possibly less efficient):

<?php
$array = Array(
  'foo' => 5,
  'bar' => 12,
  'baz' => 8
);

// pre-5.3:
echo 'The values are: '. implode(', ', array_map(
   create_function('$k,$v', 'return "$k ($v)";'),
   array_keys($array),
   $array
));

echo "\n";

// 5.3:
echo 'The values are: '. implode(', ', array_map(
   function ($k, $v) { return "$k ($v)"; },
   array_keys($array),
   $array
));
?>

Your original code looks fine to me.

5 Comments

You can replace create_function() (which is not better than eval(), because it uses eval() ;) just a side note) in php5.3 with function ($k, $v) { return "$k ($v)"; }
@KingCrunch: Indeed, an actual lambda is better in 5.3. However, I still write create_function() (which is just fine because there is no user-provided code here.. let's leave out the totally irrelevant eval()-bashing) until 5.3 is widespread on production platforms.
@KingCrunch: (I edited my question to sidestep my aversion for variable interpolation, though.)
I usually give both the 5.3-closure- as well as the pre-5.3-create_function()-solution too. I didn't want to start the old eval()-discussion again, I just thought its worth to note. However, with the 5.3-closures I don't think, its "too" verbose. I like that array_map() (and such) stuff :)
@KingCrunch: Perhaps :) I'll edit it in. Alas, with array_map, you still have to provide the keys and values as separate arrays.. which is ew.
8

You could print out the values as you iterate:

echo 'The values are: ';
foreach ($array as $key => $value) {
  $result .= "$key ($value),";
}
echo rtrim($result,',');

4 Comments

Turn the echos into a variable and after the foreach: echo trim($variable, ',');
outside the loop: $comma = ''; inside at the beginning of loop echo $comma; inside at the end of loop $comma = ',';
Feels like trim() and $comma = ''; leads more and more into hacks. Seems not that clean to me.
This is just a less neat version of the OP's original approach.
3

Taking help from the answer of @linepogl, I edited the code to make it more simple, and it works fine.

function array_map_assoc($array){
  $r = array();
  foreach ($array as $key=>$value)
    $r[$key] = "$key ($value)";
  return $r;
}

And then, just call the function using

echo implode(' , ', array_map_assoc($array));

Comments

1

Clearly, the solution proposed by Roberto Santana its the most usefull. Only one appointmen, if you want to use it for parse html attributes (for example data), you need double quotation. This is an approach:

Example: var_dump( '<td data-'.urldecode( http_build_query( ['value1'=>'"1"','value2'=>'2' ], '', ' data-' ) ).'></td>');

Output: string '<td data-value1="1" data-value2=2></td>' (length=39)

2 Comments

This answers to be the correct answer to a different question.
Programmers more typically provide code to suit the data as opposed to changing the data to suit the code.
0

Loop throw the array and put , expect the end of loop.

$index = 0; // index
$len = count($array); // Length of the array

// Loop throw the array
foreach($array as $key => $a) {
   echo "$key ($a)" . ($index != $len - 1 ? ',' : '');
   $index++;
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.