Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I have an array in PHP:

array (size=xxx)
  0 => 
    array (size=9)
      'cat' => string 'FIRST CAT'
      'dur' => string '10'
      'type' => string 'Type description 10'
      'start' => string '00:00'
      'end' => string '01:00'
      'desc' => string 'Event description 10-1'
      'price' => string 'xxx'
      'extra' => string 'yyy'
  1 => 
    array (size=9)
      'cat' => string ''
      'dur' => string ''
      'type' => string ''
      'start' => string '01:00'
      'end' => string '02:00'
      'desc' => string 'Event description 10-2'
      'price' => string ''
      'extra' => string ''
  2 => 
    array (size=9)
      'cat' => string ''
      'dur' => string ''
      'type' => string ''
      'start' => string '02:00'
      'end' => string '03:00'
      'desc' => string 'Event description 10-3'
      'price' => string ''
      'extra' => string ''
  3 => 
    array (size=9)
      'cat' => string ''
      'dur' => string '20'
      'type' => string 'Type description 20'
      'start' => string '00:00'
      'end' => string '01:00'
      'desc' => string 'Event description 20-1'
      'price' => string 'xxx'
      'extra' => string 'yyy'
  4 => 
    array (size=9)
      'cat' => string ''
      'dur' => string ''
      'type' => string ''
      'start' => string '01:00'
      'end' => string '02:00'
      'desc' => string 'Event description 20-2'
      'price' => string ''
      'extra' => string ''
  5 => 
    array (size=9)
      'cat' => string ''
      'dur' => string ''
      'type' => string 'Type description 21'
      'start' => string '00:00'
      'end' => string '01:00'
      'desc' => string 'Event description 21-1'
      'price' => string 'xxx'
      'extra' => string 'yyy'
  6 => 
    array (size=9)
      'cat' => string ''
      'dur' => string ''
      'type' => string ''
      'start' => string '01:00'
      'end' => string '02:00'
      'desc' => string 'Event description 21-2'
      'price' => string ''
      'extra' => string ''
  7 => 
    array (size=9)
      'cat' => string 'SECOND CAT'
      'dur' => string '10'
      'type' => string 'Type description 100'
      'start' => string '00:00'
      'end' => string '01:00'
      'desc' => string 'Event description 100-1'
      'price' => string 'xxx'
      'extra' => string 'yyy'
  8 => 
    array (size=9)
      'cat' => string ''
      'dur' => string ''
      'type' => string ''
      'start' => string '01:00'
      'end' => string '02:00'
      'desc' => string 'Event description 100-2'
      'price' => string ''
      'extra' => string ''
  9 => 
    array (size=9)
      'cat' => string ''
      'dur' => string '20'
      'type' => string 'Type description 200'
      'start' => string '00:00'
      'end' => string '01:00'
      'desc' => string 'Event description 200-1'
      'price' => string 'xxx'
      'extra' => string 'yyy'
  10 => 
    array (size=9)
      'cat' => string ''
      'dur' => string ''
      'type' => string ''
      'start' => string '01:00'
      'end' => string '02:00'
      'desc' => string 'Event description 200-2'
      'price' => string ''
      'extra' => string ''
  11 => 
    array (size=9)
      'cat' => string ''
      'dur' => string ''
      'type' => string 'Type description 210'
      'start' => string '00:00'
      'end' => string '01:00'
      'desc' => string 'Event description 210-1'
      'price' => string 'xxx'
      'extra' => string 'yyy'
  etc...

I need to group this array first by cat, then by dur, then type. This type array would have two strings - price and extra and another array which would consist of all the events data - start, end and desc. Final array outline (based on example above) should look like this:

'FIRST CAT'                                           // 'cat'
    '10'                                              // 'dur'
      'Type description 10', 'xxx', 'yyy'             // 'type', 'price', 'extra'
          (array of events)
          '00:00', '01:00', 'Event description 10-1'  // 'start', 'end', 'desc'
          '01:00', '02:00', 'Event description 10-2'  // 'start', 'end', 'desc'
          '02:00', '03:00', 'Event description 10-3'  // 'start', 'end', 'desc'
    '20'
      'Type description 20', 'xxx', 'yyy'
          (array of events)
          '00:00', '01:00', 'Event description 20-1'
          '01:00', '02:00', 'Event description 20-2'
      'Type description 21', 'xxx', 'yyy'
          (array of events)
          '00:00', '01:00', 'Event description 21-1'
          '01:00', '02:00', 'Event description 21-2'
'SECOND CAT'
    '10'
      'Type description 100', 'xxx', 'yyy'
          (array of events)
          '00:00', '01:00', 'Event description 100-1'
          '01:00', '02:00', 'Event description 100-2'
    '20'
      'Type description 200', 'xxx', 'yyy'
          (array of events)
          '00:00', '01:00', 'Event description 200-1'
          '01:00', '02:00', 'Event description 200-2'
      'Type description 210', 'xxx', 'yyy'
          (array of events)
          '00:00', '01:00', 'Event description 210-1'
          '01:00', '02:00', 'Event description 210-2'

What would be the simplest way to convert my existing array to the one I need in the end?

share|improve this question
What have you already tried? And what failed? – nl-x Jun 6 at 12:08
1  
@nl-x I tried to follow the logic behind this post stackoverflow.com/questions/12706359/php-array-group but I'm a bit confused because my original array have empty values... – errata Jun 6 at 12:52

2 Answers

up vote 1 down vote accepted

The following does what you're looking for:

$out = array();
foreach ($arr as $key => $value){
    $cat = $value['cat'];
    $dur = $value['dur'];
    $type = $value['type'];
    $out[$cat][$dur][$type][] = $value['start'].', '.$value['end'].', '.$value['desc'];
}
print_r($out);

EDIT:

I modified my code because of a request to use the last category when the category is empty. So, here's my modified code:

    $out = array();
    $last_cat = '';
    foreach ($arr as $key => $value){
        $cat = $value['cat'];
        $dur = $value['dur'];
        $type = $value['type'];
        if (empty($cat)){
            $cat = $last_cat;
        } else {
            $last_cat = $cat;
        }
        $out[$cat][$dur][$type][] = $value['start'].', '.$value['end'].', '.$value['desc'];
    }
    print_r($out);

The ouput of this code is as follows:

[FIRST CAT] => Array(
        [10] => Array(
            [Type description 10] => Array(
                [0] => 00:00, 01:00, Event description 10-1
            )
        )
        [] => Array(
            [] => Array(
                    [0] => 01:00, 02:00, Event description 10-2
                    [1] => 02:00, 03:00, Event description 10-3
                    [2] => 01:00, 02:00, Event description 20-2
                    [3] => 01:00, 02:00, Event description 21-2
                )

            [Type description 21] => Array(
                    [0] => 00:00, 01:00, Event description 21-1
                )
        )
        [20] => Array(
            [Type description 20] => Array(
                    [0] => 00:00, 01:00, Event description 20-1
                )
        )
    )
[SECOND CAT] => Array(
        [10] => Array(
            [Type description 100] => Array(
                    [0] => 00:00, 01:00, Event description 100-1
                )
            )
        [] => Array(
            [] => Array(
                    [0] => 01:00, 02:00, Event description 100-2
                    [1] => 01:00, 02:00, Event description 200-2
                )
            [Type description 210] => Array(
                    [0] => 00:00, 01:00, Event description 210-1
                )
            )
        [20] => Array(
            [Type description 200] => Array(
                    [0] => 00:00, 01:00, Event description 200-1
                )
            )
    )
share|improve this answer
This is very helpful, but my $out has additional "blank category" array ('FIRST CAT', '' and 'SECOND CAT) which is not the desired output. I see now how should I construct my output and will give it a try :) – errata Jun 6 at 12:50
Do you want to eliminate all data that has a blank catecory? Your original array had a lot of data with no category. – Pé de Leão Jun 6 at 12:53
No, I don't want to eliminate that, I'd like to group it under the belonging category. – errata Jun 6 at 12:54
That's what I did. There is a group in the array that has no category name. The key in the output appears as empty brackets: []. Maybe I'm not understanding "belonging category." If the data has no category, to what catagory does it belong? – Pé de Leão Jun 6 at 13:01
Ah yes, the original array is a bit 'dumb' :) The data belongs to specific category until the array don't have another cat defined. In my example, array elements from 0-6 belong to 'FIRST CAT' and elements from 7-11 belong to 'SECOND CAT'. – errata Jun 6 at 13:07
show 1 more comment

I think it would be best to use the http://php.net/manual/en/function.ksort.php ksort function.

share|improve this answer
Hm, but I don't need to sort it, I need to group my original array... – errata Jun 6 at 12:43

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.