Php 基于两列对多维数组中的数据进行分组

Php 基于两列对多维数组中的数据进行分组,php,arrays,multidimensional-array,grouping,array-merge,Php,Arrays,Multidimensional Array,Grouping,Array Merge,我有一个关联数组的索引数组,如下所示: [ ['brand' => 'ABC', 'model' => 'xyz', 'size' => 13], ['brand' => 'QWE', 'model' => 'poi', 'size' => 23], ['brand' => 'ABC', 'model' => 'xyz', 'size' => 18] ]; 我需要根据品牌和型号将数据缩减/合并/重组为组。如果在这两列

我有一个关联数组的索引数组,如下所示:

[
    ['brand' => 'ABC', 'model' => 'xyz', 'size' => 13],
    ['brand' => 'QWE', 'model' => 'poi', 'size' => 23],
    ['brand' => 'ABC', 'model' => 'xyz', 'size' => 18]
];
我需要根据
品牌
型号
将数据缩减/合并/重组为组。如果在这两列上分组时,
品牌
&
型号
组合出现多次,则
大小
值应形成索引子数组。否则,
size
值可以保留为单个字符串值

我期望的结果是:

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

就算法而言,您只需:

  • 创建一个空数组

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

  • 如果已经有一个品牌/型号条目,只需将该尺寸添加到子数组(如果尚未存在)

  • 您可以按如下方式实现此功能(虽然很粗糙,但它是有效的):

    “升级”到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']);
      }
    }
    

    不再重复…

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

    临时复合键允许快速查找以前遇到的
    品牌
    -
    型号
    对。使用定界字符(两个值中均未使用)分隔复合字符串中的每个值非常重要,这样就不会出现意外的“数据冲突”

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

    经典的foreach()
    :()()

    使用
    array\u reduce()进行函数编程
    :()


    如果我是诚实的,我会为我的输出创建一个一致的数据结构,并且大小总是子数组。下面是如何修改上述代码段,以便在第一次相遇时将size元素转换为数组,并将随后遇到的所有size值推送到该组的子数组中:()


    如果(!in_array($element['size'],$newArray[$elementKey]['size'])
    只在品牌/型号已经存在的情况下添加新尺寸:p.@middaparka:尝试使用包含重复尺寸的数组,您将看到发生了什么:p.是否可以在不知道密钥的情况下使用此代码?数据不统一,键可以是任何单词。例如,替换:$elementKey=$element['brand'].'$元素[‘模型’];类似于:$elementKey=$element[$key1].''$元素[$key2]@Derick-如果只是因为您需要从一些键生成查找,那么就不是这样了。这就是说,只要您始终有“n”键(在查找中使用),并且其余数据(大小除外)不相关,您就可以在“否-创建新元素”位期间使用array_键添加其余数据。
    if(isset($data['size'])和&is_array($data['size']){
    是100%无用的。子数组键是无条件声明的,并且将始终是一个数组,并且始终是非空的。在一个完美的世界中,我同意你的看法。编写过于详细的验证有助于在数月/数年后阅读代码时更清楚地说明目的,同时也是验证内容的一个良好实践-你永远不知道是什么在现有代码的中间添加了多少代码。这种编码方式在过去一年中保存了好几次。我保留了它。不,你并没有影响我。这不是我的观点。这是一个真实的、逻辑的、可证明的事实。你正在编写第一个循环生成的<代码> $NexAlxAlgs数组的第二个循环。o、 这不是关于“一个完美的世界”——这是关于计算机科学的现实。你的脚本始终没有理由执行这些检查。反驳任何相反的观点都是毫无意义的,很可能会让研究人员感到困惑,并教给他们无意义的编码实践。
    //$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"];
    }
    
    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']);
      }
    }
    
    $result = [];
    foreach ($array as $row) {
        $compositeKey = $row['brand'] . '_' . $row['model'];
        if (!isset($result[$compositeKey])) {
            $result[$compositeKey] = $row;
        } else {
            $result[$compositeKey]['size'] = array_merge(
                (array)$result[$compositeKey]['size'],
                [$row['size']]
            );
        }
    }
    var_export($result);
    
    var_export(
        array_values(
            array_reduce(
                $array,
                function ($carry, $row) {
                    $compositeKey = $row['brand'] . '_' . $row['model'];
                    if (!isset($carry[$compositeKey])) {
                        $carry[$compositeKey] = $row;
                    } else {
                        $carry[$compositeKey]['size'] = array_merge(
                            (array)$carry[$compositeKey]['size'],
                            [$row['size']]
                        );
                    }
                    return $carry;
                }
            )
        )
    );
    
    $result = [];
    foreach ($array as $row) {
        $compositeKey = $row['brand'] . '_' . $row['model'];
        if (!isset($result[$compositeKey])) {
            $row['size'] = (array)$row['size'];
            $result[$compositeKey] = $row;
        } else {
            $result[$compositeKey]['size'][] = $row['size'];
        }
    }
    var_export(array_values($result));