Merge and group array data

2019-04-11 21:10发布

问题:

How to group this:

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

into this:

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

I want to group by BRAND and MODEL, but insert an array in the SIZE, since this one is not the same.

回答1:

In terms of the algorithm, you simply need to:

  1. Create an empty array.

  2. Scan each array element in the source array creating a new element (in the empty array) for each new brand/model encountered and adding the size sub-array.

  3. If there's already a brand/model entry, simply add the size to the sub-array if it's not already present.

You could implement this as follows (crude, but it works):

<?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);
?>

Incidentally, for ease of access I've made it so that the size sub-array is always an array. (i.e.: You don't have to allow for it to potentially only be an element.)



回答2:

//$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"];
}


回答3:

"Upgrade" to knarf's snippet....

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']);
  }
}

No duplicates anymore...