Group duplicate array keys in a multidimensional array into subarray
I have a multidimensional array called $songs
, which outputs the following:
Array
(
[0] => Array
(
[Michael Jackson] => Thriller
)
[1] => Array
(
[Michael Jackson] => Rock With You
)
[2] => Array
(
[Teddy Pendergrass] => Love TKO
)
[3] => Array
(
[A开发者_开发知识库CDC] => Back in Black
)
)
I would like to merge the arrays which have duplicate keys, so I can get the following:
Array
(
[0] => Array
(
[Michael Jackson] => Array
(
[0] => Thriller
[1] => Rock With You
)
)
[1] => Array
(
[Teddy Pendergrass] => Love TKO
)
[2] => Array
(
[ACDC] => Back in Black
)
)
How do I do this?
Bonus points for giving me the code to output the array like:
<h2>Michael Jackson</h2>
<ul>
<li>Thriller</li>
<li>Rock With You</li>
</ul>
<h2>Teddy Pendergrass</h2>
<ul>
<li>Love TKO</li>
</ul>
<h2>ACDC</h2>
<ul>
<li>Back in Black</li>
</ul>
This should do it, it's not exactly what you want but I don't see a reason why you'd need to index the resulting array numerically, and then by artist.
$source = array(
array('Michael Jackson' => 'Thriller'),
array('Michael Jackson' => 'Rock With You'),
array('Teddy Pendergrass' => 'Love TKO'),
array( 'ACDC' => 'Back in Black')
);
$result = array();
foreach($source as $item) {
$artist = key($item);
$album = current($item);
if(!isset($result[$artist])) {
$result[$artist] = array();
}
$result[$artist][] = $album;
}
And you can loop the $result
array and build your HTML like this:
foreach($result as $artist => $albums) {
echo '<h2>'.$artist.'</h2>';
echo '<ul>';
foreach($albums as $album) {
echo '<li>'.$album.'</li>';
}
echo '</ul>';
}
Which would result in a similar list that you described.
The native PHP function array_merge_recursive()
will cut 9 lines of code down to 1 thanks to the splat operator.
Code: (Demo)
$result = array_merge_recursive(...$songs);
Output:
array (
'Michael Jackson' =>
array (
0 => 'Thriller',
1 => 'Rock With You',
),
'Teddy Pendergrass' => 'Love TKO',
'ACDC' => 'Back in Black',
)
This does not create your desired array structure; it creates the most compact version of your associative data.
When it comes to printing your data, I recommend using an html template string and feeding data into its placeholders.
Because the grouped $songs
data may be scalar or iterable (by consequence of array_merge_recursive()
), that variable must be explicitly cast as array
type data before feeding it into implode()
.
$template = <<<HTML
<h2>%s</h2>
<ul>
<li>%s</li>
</ul>
HTML;
foreach ($result as $artist => $songs) {
printf(
$template,
$artist,
implode('</li><li>', (array)$songs)
);
}
Output:
<h2>Michael Jackson</h2>
<ul>
<li>Thriller</li><li>Rock With You</li>
</ul>
<h2>Teddy Pendergrass</h2>
<ul>
<li>Love TKO</li>
</ul>
<h2>ACDC</h2>
<ul>
<li>Back in Black</li>
</ul>
精彩评论