tags:

views:

65

answers:

3

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

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

middaparka
It probably should be `if(!in_array($element['size'], $newArray[$elementKey]['size']))` though, to only add new sizes if brand/model already exists :p.
wimvds
Wow! thank you very much! You saved my day! Cheers from Japan!
Derick
@Derick - No problem. Welcome to stackoverflow. :-)
middaparka
@wimvds - Good point. I've updated the code. :-)
middaparka
@middaparka: Try it with an array containing a duplicate size, you'll see what happens :p.
wimvds
@wimvds - Yup, already fixed it. Thanks again. :-)
middaparka
Is it possible to use this code without know the keys?The data is not uniform and the keys can be any word.For example in replacement of:$elementKey = $element['brand'] . '_' . $element['model'];Something like:$elementKey = $element[$key1] . '_' . $element[$key2];??
Derick
@Derick - Not really if only because of the fact that you need to generate a lookup from some of the keys. That said, as long you always had 'n' keys (which were used in the lookup) and the rest of the data (other than size) was irrelevant you could use array_keys to add the rest during the "No - create the new element" bit.
middaparka
Ok, thanks. Really helped a lot.
Derick
A: 
//$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"];
}
Knarf
This will always add the size, even if it's a duplicate.
middaparka
Is an option too! Thanks for helping!
Derick
A: 
vlad b.