【问题标题】:Grouping and Merging array in PHPPHP中的分组和合并数组
【发布时间】:2014-11-21 09:39:49
【问题描述】:

我有一个下面提到的数组。

$array = array(
        '0' => array(
            'names' => array(0 => 'Apple'),
            'group' => 1
        ),
        '1' => array(
            'names' => array(0 => 'Mango'),
            'group' => 1
        ),
        '2' => array(
            'names' => array(0 => 'Grapes'),
            'group' => 1
        ),
        '3' => array(
            'names' => array(0 => 'Tomato'),
            'group' => 2
        ),
        '4' => array(
            'names' => array(0 => 'Potato'),
            'group' => 2
        )
    );

我想要这样的结果,如果数组键“group”的值相同,那么键“names”的值应该被合并。我想要下面提到的输出。

    $array = array(
        '0' => array(
            'names' => array(0 => 'Apple', 1 => 'Mango', 2 => 'Grapes'),
            'group' => 1
        ),
        '1' => array(
            'names' => array(0 => 'Tomato', 1 => 'Potato'),
            'group' => 2
        )
    );

【问题讨论】:

    标签: php arrays multidimensional-array grouping array-merge


    【解决方案1】:

    PHP函数array_reduce()的完美使用示例:

    $array = array_values(
        array_reduce(
            $array,
            function (array $carry, array $item) {
                // Extract the group name into a variable for readability
                // and speed; it is used several times velow
                $key = $item['group'];
                // Initialize the group if it is the first entry in this group
                if (! array_key_exists($key, $carry)) {
                    $carry[$key] = array(
                        'names' => array(),
                        'group' => $key,
                    );
                }
                // Add the new names to the group in the output array
                $carry[$key]['names'] = array_merge($carry[$key]['names'], $item['names']);
    
                // Return the partial result
                return $carry;
            },
            array()
        )
    );
    

    代码使用array_reduce() 迭代构建一个包含预期值的新数组。

    如果需要,回调函数会创建组,然后将已处理项目的名称合并到结果数组中的现有组中。

    使用array_reduce() 生成的数组使用group 的值进行索引,按照它们在输入数组中出现的顺序。对于发布的数组,它们的键是12。如果您不关心密钥,请删除对 array_values() 的调用,以提高速度和可读性。

    函数array_values() 删除键并返回使用从零开始的连续数字键索引的数组(如问题中列出的键)。

    【讨论】:

      【解决方案2】:

      通过简单地将 group 值用作临时关联键,您可以快速确定(在迭代时)是否应该存储整行数据,或者只是将 names 值附加到现有子数组。

      *如果您的项目数据可能包含具有多个 names 值的输入子数组,您应该更新您的问题以澄清这种可能性。 (Fringe Demo) (Fringe Demo2)

      代码:(Demo)

      foreach ($array as $row) {
          if (!isset($result[$row['group']])) {
              $result[$row['group']] = $row;
          } else {
              $result[$row['group']]['names'][] = $row['names'][0];
          }
      }
      
      var_export(array_values($result));
      

      输出:

      array (
        0 => 
        array (
          'names' => 
          array (
            0 => 'Apple',
            1 => 'Mango',
            2 => 'Grapes',
          ),
          'group' => 1,
        ),
        1 => 
        array (
          'names' => 
          array (
            0 => 'Tomato',
            1 => 'Potato',
          ),
          'group' => 2,
        ),
      )
      

      您可以使用array_values() 从结果数组中删除临时关联键。

      【讨论】:

        【解决方案3】:
        <?php
            //initialize our array
            $array = array(
                '0' => array(
                    'names' => array(0 => 'Apple'),
                    'group' => 1
                ),
                '1' => array(
                    'names' => array(0 => 'Mango'),
                    'group' => 1
                ),
                '2' => array(
                    'names' => array(0 => 'Grapes'),
                    'group' => 1
                ),
                '3' => array(
                    'names' => array(0 => 'Tomato'),
                    'group' => 2
                ),
                '4' => array(
                    'names' => array(0 => 'Potato'),
                    'group' => 2
                )
            );
            //result will be here
            $result = array();
        
            foreach ($array as $key => $value) {
                //check if we have keys group or names to avoid errors
                if(!isset($value['group']) || !isset($value['names']))
                    continue;
        
                //make a key in result array if its not exist
                if(!isset($result[$value['group']]))
                {
                    $result[$value['group']] = $value['names'];
                }
                else
                {
                    //add a values to key if it exists
                    $result[$value['group']] = array_merge($result[$value['group']], 
                        $value['names']);
                    //filter same values
                    $result[$value['group']] = array_values(array_unique($result[$value['group']]));
                }
            }
            print_r($result);
        

        【讨论】:

          【解决方案4】:

          您可以迭代数组并将所有内容存储在一个单独的数组中到组中。之后,您可以创建所需格式的输出数组,如下所示:

          $groups = array();
          foreach($array as $subArray) {
              if (!array_key_exists($subArray['group'], $groups)) {
                  $groups[$subArray['group']] = array();
              }
              $groups[$subArray['group']] = array_merge($groups[$subArray['group']], $subArray['names']);
          }
          
          $result = array();
          foreach($groups as $groupId => $group) {
              $result[] = array(
                  'names' => $group,
                  'group' => $groupId,
              );
          }
          
          print_r($result);
          

          【讨论】:

          • $subArray['names']中大于1个值将无法正常工作
          • @fiction 现在可以了(但这不是必需的,现在是吗?)
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-12-12
          • 1970-01-01
          • 1970-01-01
          • 2023-03-15
          • 1970-01-01
          • 2015-07-25
          • 1970-01-01
          相关资源
          最近更新 更多