【问题标题】:Group duplicate array keys in a multidimensional array into subarray将多维数组中的重复数组键分组到子数组中
【发布时间】:2010-01-29 21:49:59
【问题描述】:

我有一个名为$songs 的多维数组,它输出以下内容:

Array
(
    [0] => Array
        (
            [Michael Jackson] => Thriller
        )

    [1] => Array
        (
            [Michael Jackson] => Rock With You
        )

    [2] => Array
        (
            [Teddy Pendergrass] => Love TKO
        )

    [3] => Array
        (
            [ACDC] => Back in Black
        )
)

我想合并具有重复键的数组,所以我可以得到以下内容:

Array
(
    [0] => Array
        (
            [Michael Jackson] => Array
            (
                [0] => Thriller
                [1] => Rock With You
            )
        )

    [1] => Array
        (
            [Teddy Pendergrass] => Love TKO
        )

    [2] => Array
        (
            [ACDC] => Back in Black
        )
)

我该怎么做?

给我输出数组的代码的奖励积分如下:

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

【问题讨论】:

    标签: php arrays multidimensional-array grouping html-lists


    【解决方案1】:

    应该这样做,这不是您想要的,但我看不出为什么您需要先对结果数组进行数字索引,然后再按艺术家。

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

    您可以循环 $result 数组并像这样构建您的 HTML:

    foreach($result as $artist => $albums) {
        echo '<h2>'.$artist.'</h2>';
        echo '<ul>';
        foreach($albums as $album) {
            echo '<li>'.$album.'</li>';
        }
        echo '</ul>';
    }
    

    这将导致您描述的类似列表。

    【讨论】:

      【解决方案2】:

      原生 PHP 函数 array_merge_recursive() 将 9 行代码减少到 1 行,这要归功于 splat 运算符。

      代码:(Demo)

      $result = array_merge_recursive(...$songs);
      

      输出:

      array (
        'Michael Jackson' => 
        array (
          0 => 'Thriller',
          1 => 'Rock With You',
        ),
        'Teddy Pendergrass' => 'Love TKO',
        'ACDC' => 'Back in Black',
      )
      

      这不会创建您想要的数组结构;它会创建最紧凑的关联数据版本。

      在打印数据时,我建议使用 html 模板字符串并将数据输入到其占位符中。

      因为分组的$songs 数据可能是标量或可迭代的(array_merge_recursive() 的结果),所以该变量必须显式转换为array 类型数据,然后才能将其输入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)
          );
      }
      

      输出:

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

      【讨论】:

        猜你喜欢
        • 2013-09-18
        • 1970-01-01
        • 1970-01-01
        • 2011-10-22
        • 2016-12-11
        • 2011-10-18
        • 1970-01-01
        • 2023-04-02
        • 1970-01-01
        相关资源
        最近更新 更多