合并和分组数组数据

时间:2010-08-12 15:00:01

标签: php arrays grouping

如何分组:

Array(
      [0] => Array(
                  [brand] => 'ABC',
                  [model] => 'xyz',
                  [size] => 13
      )
      [1] => Array(
                  [brand] => 'QWE',
                  [model] => 'poi',
                  [size] => 23
      )
      [2] => Array(
                  [brand] => 'ABC',
                  [model] => 'xyz',
                  [size] => 18
      ) )

进入这个:

Array(
      [0] => Array(
                  [brand] => 'ABC',
                  [model] => 'xyz',
                  [size] => Array(
                                 13,
                                 18
                            )
      )
      [1] => Array(
                  [brand] => 'QWE',
                  [model] => 'poi',
                  [size] => 23
      ) )

我想按BRAND和MODEL分组,但在SIZE中插入一个数组,因为这个不一样。

4 个答案:

答案 0 :(得分:3)

就算法而言,您只需要:

  1. 创建一个空数组。

  2. 扫描源数组中的每个数组元素,为遇到的每个新品牌/型号创建一个新元素(在空数组中)并添加size子数组。

  3. 如果已有品牌/型号条目,只需将尺寸添加到子阵列(如果尚未存在)。

  4. 你可以按如下方式实现:粗略,但它有效:

    <?php
        // Test data.
        $sourceArray = array(array('brand'=>'ABC', 'model'=>'xyz', 'size'=>13),
                             array('brand'=>'QWE', 'model'=>'poi', 'size'=>23),
                             array('brand'=>'ABC', 'model'=>'xyz', 'size'=>18),
                            );
        $newArray = array();
    
        // Create a new array from the source array. 
        // We'll use the brand/model as a lookup.
        foreach($sourceArray as $element) {
    
            $elementKey = $element['brand'] . '_' . $element['model'];
    
            // Does this brand/model combo already exist?
            if(!isset($newArray[$elementKey])) {
                // No - create the new element.
                $newArray[$elementKey] = array('brand'=>$element['brand'],
                                               'model'=>$element['model'], 
                                               'size'=>array($element['size']),
                                               );
            }
            else {
                // Yes - add the size (if it's not already present).
                if(!in_array($element['size'], $newArray[$elementKey]['size'])) {
                    $newArray[$elementKey]['size'][] = $element['size'];
                }
            }
        }
    
        // *** DEBUG ***
        print_r($newArray);
    ?>
    

    顺便提一下,为了便于访问,我已经做到了这样,大小子数组总是一个数组。 (即:您不必允许它只是一个元素。)

答案 1 :(得分:0)

//$array is the array in your first example.

foreach($array as $item) {
  $itemname = $item["brand"] . "_" . $item["model"]

  $new_array[$itemname]["brand"]  = $item["brand"];
  $new_array[$itemname]["model"]  = $item["model"];
  $new_array[$itemname]["size"][] = $item["size"];
}

答案 2 :(得分:0)

“升级”到knarf的片段......

foreach($array as $item) {
  $itemname = $item["brand"] . "_" . $item["model"]

  $new_array[$itemname]["brand"]  = $item["brand"];
  $new_array[$itemname]["model"]  = $item["model"];
  $new_array[$itemname]["size"][ $item["size"] ] = 1;
}

foreach($new_array as $itemname=>$data) {
  if(isset($data['size']) && is_array($data['size'])) {
    $new_array[$itemname]['size']=array_keys($new_array[$itemname]['size']);
  }
}

不再重复......

答案 3 :(得分:0)

我将从字面上解释这个问题,并提供确切描述的输出结构。

临时复合键允许快速查找以前遇到的brand-model对。重要的是,使用定界字符(两个值均未使用)分隔复合字符串中的每个值,以免发生意外的“数据冲突”。

如果给定的“品牌模型”组合仅发生一次,则原始行结构将被推入结果数组。否则,“大小”数据将转换为索引数组,随后的唯一大小值将推入子数组。

代码:(Demo

$inventory = [
    ['brand' => 'ABC', 'model' => 'xyz', 'size' => 13],
    ['brand' => 'QWE', 'model' => 'poi', 'size' => 23],
    ['brand' => 'ABC', 'model' => 'xyz', 'size' => 18],
    ['brand' => 'QWE', 'model' => 'poi', 'size' => 23], // duplicate
    ['brand' => 'ABC', 'model' => 'xyz', 'size' => 18], // duplicate 
];

foreach ($inventory as $item) {
    $key = $item['brand'] . '_' . $item['model'];
    if (!isset($result[$key])) {
        $result[$key] = $item;
    } elseif (!in_array($item['size'], (array)$result[$key]['size'])) {
        $result[$key]['size'] = (array)$result[$key]['size'];
        $result[$key]['size'][] = $item['size'];
    }
}

var_export(array_values($result));

输出:

array (
  0 => 
  array (
    'brand' => 'ABC',
    'model' => 'xyz',
    'size' => 
    array (
      0 => 13,
      1 => 18,
    ),
  ),
  1 => 
  array (
    'brand' => 'QWE',
    'model' => 'poi',
    'size' => 23,
  ),
)

老实说,我会为我的输出创建一个一致的数据结构,并且大小始终是子数组。以下是修改上述代码段的方法,以便在首次遇到时将size元素转换为数组:

Demo

foreach ($inventory as $item) {
    $key = $item['brand'] . '_' . $item['model'];
    if (!isset($result[$key])) {
        $item['size'] = (array)$item['size'];
        $result[$key] = $item;
    } elseif (!in_array($item['size'], $result[$key]['size'])) {
        $result[$key]['size'][] = $item['size'];
    }
}

var_export(array_values($result));

这两个代码片段均以最直接,最简洁的方式正确地解释了问题。