skip to Main Content

I am working with an array that is multi-dimensional and contains a nested array. The array has a duplicate and I would like to merge the array so that the array within each of the duplicate keys are combined into one.

Here is an example of the array:

$showTimes = array(
    array(
        'day' => 'Monday',
        'details' => array(
            array(
                'theater' => 'Theater 1',
                'times' => '1:00, 7:00, 8:00'
            )
        )
    ),
    array(
        'day' => 'Tuesday',
        'details' => array(
            array(
                'theater' => 'Theater 1',
                'times' => '2:00, 5:00'
            )
        )
    ),
    array(
        'day' => 'Tuesday',
        'details' => array(
            array(
                'theater' => 'Theater 2',
                'times' => '4:00, 9:00'
            )
        )
    ),
    array(
        'day' => 'Wednesday',
        'details' => array(
            array(
                'theater' => 'Theater 1',
                'times' => '1:00, 7:00, 8:00'
            )
        )
    )
);

I would like to combine the two instances of Tuesday so that the theaters and show times for that day both exist within a single instance. I have found some similar questions, but nothing with the depth of my array. From what I’ve seen it has to do with using the array key but I am completely lost. Here’s where I’m currently at:

$new_array = array();
foreach ($showTimes as $subArray) {
    foreach ($subArray as $key=>$value) {
        $new_array['details'][$key] = $value;
    }
}
print_r($new_array);

The desired output would look like this:

Array
(
    [0] => Array
        (
            [day] => Monday
            [details] => Array
                (
                    [0] => Array
                        (
                            [theater] => Theater 1
                            [times] => 1:00, 7:00, 8:00
                        )

                )

        )

    [1] => Array
        (
            [day] => Tuesday
            [details] => Array
                (
                    [0] => Array
                        (
                            [theater] => Theater 1
                            [times] => 2:00, 5:00
                        )

                    [1] => Array
                        (
                            [theater] => Theater 2
                            [times] => 4:00, 9:00
                        )

                )

        )

    [2] => Array
        (
            [day] => Wednesday
            [details] => Array
                (
                    [0] => Array
                        (
                            [theater] => Theater 1
                            [times] => 1:00, 7:00, 8:00
                        )

                )

        )

)

2

Answers


  1. I built this out for fun … I believe it does what you are asking …

    <?php
    
    $showTimes = array(
        array(
            'day' => 'Monday',
            'details' => array(
                array(
                    'theater' => 'Theater 1',
                    'times' => '1:00, 7:00, 8:00'
                )
            )
        ),
        array(
            'day' => 'Tuesday',
            'details' => array(
                array(
                    'theater' => 'Theater 1',
                    'times' => '2:00, 5:00'
                )
            )
        ),
        array(
            'day' => 'Tuesday',
            'details' => array(
                array(
                    'theater' => 'Theater 2',
                    'times' => '4:00, 9:00'
                )
            )
        ),
        array(
            'day' => 'Wednesday',
            'details' => array(
                array(
                    'theater' => 'Theater 1',
                    'times' => '1:00, 7:00, 8:00'
                )
            )
        )
    );
    $final_arr = []; // Will end up being final array
    $completed = []; // Array we use to check if the day is built already
    foreach ($showTimes as $key => $showTime) {
        
        $tmp_arr = []; // tmp array to store ['details']
        
        // Check to see if day is built out .. If so continue
        $continue = false;  
        foreach($completed as $item){
            if ($showTime['day'] === $item){
                $continue = true;
            }
        }
        if($continue){
            continue;
        }
        // End Check
    
        // Add to completed since day isn't built yet
        $completed[] = $showTime['day']; 
    
        // Loop through main array (again ... for check)
        foreach ($showTimes as $tmp_key => $tmp_ShowTime) {
            
            // If the day matches
            if ($tmp_ShowTime['day'] === $showTime['day']) {
                //build temporary ['details'] array
                $tmp_arr[$tmp_key] = $tmp_ShowTime['details'][0];
            }
        }
        // Change ['details'] in main array to tmp one we assigned
        $showTime['details'] = $tmp_arr;
        
        // Add adjusted day to final array
        $final_arr[] = $showTime;
    }
    
    print_r($final_arr);
    

    The output should look like:

    Array
    (
        [0] => Array
            (
                [day] => Monday
                [details] => Array
                    (
                        [0] => Array
                            (
                                [theater] => Theater 1
                                [times] => 1:00, 7:00, 8:00
                            )
    
                    )
    
            )
    
        [1] => Array
            (
                [day] => Tuesday
                [details] => Array
                    (
                        [1] => Array
                            (
                                [theater] => Theater 1
                                [times] => 2:00, 5:00
                            )
    
                        [2] => Array
                            (
                                [theater] => Theater 2
                                [times] => 4:00, 9:00
                            )
    
                    )
    
            )
    
        [2] => Array
            (
                [day] => Wednesday
                [details] => Array
                    (
                        [3] => Array
                            (
                                [theater] => Theater 1
                                [times] => 1:00, 7:00, 8:00
                            )
    
                    )
    
            )
    
    )
    
    Login or Signup to reply.
  2. With a foreach loop:

    $showTimes = [
      [
        'day'     => 'Monday',
        'details' => [ [ 'theater' => 'Theater 1', 'times' => '1:00, 7:00, 8:00' ] ]
      ],
      [
        'day'     => 'Tuesday',
        'details' => [ [ 'theater' => 'Theater 1', 'times' => '2:00, 5:00' ] ]
      ],
      [
        'day'     => 'Tuesday',
        'details' => [ [ 'theater' => 'Theater 2', 'times' => '4:00, 9:00' ] ]
      ],
      [
        'day'     => 'Wednesday',
        'details' => [ [ 'theater' => 'Theater 1', 'times' => '1:00, 7:00, 8:00' ] ]
      ]
    ];
    
    $result = [];
    $last_day = '';
    
    foreach ($showTimes as $showTime) {
      if ($last_day === $showTime['day']) {
        $result[array_key_last($result)]['details'][] = $showTime['details'][0];
      } else {
        $result[] = $showTime;
        $last_day = $showTime['day'];
      }
    }
    
    print_r($result);
    

    The equivalent with array_reduce:

    $showTimes = [
      [
        'day'     => 'Monday',
        'details' => [ [ 'theater' => 'Theater 1', 'times' => '1:00, 7:00, 8:00' ] ]
      ],
      [
        'day'     => 'Tuesday',
        'details' => [ [ 'theater' => 'Theater 1', 'times' => '2:00, 5:00' ] ]
      ],
      [
        'day'     => 'Tuesday',
        'details' => [ [ 'theater' => 'Theater 2', 'times' => '4:00, 9:00' ] ]
      ],
      [
        'day'     => 'Wednesday',
        'details' => [ [ 'theater' => 'Theater 1', 'times' => '1:00, 7:00, 8:00' ] ]
      ]
    ];
    
    $result =
      array_reduce(
        $showTimes,
        function ($carry, $item) {
          if ($carry['last_day'] === $item['day']) {
            $carry['result'][array_key_last($carry['result'])]['details'][] = $item['details'][0];
          } else {
            $carry['result'][] = $item;
            $carry['last_day'] = $item['day'];
          }
          return $carry;
        },
        [ 'result' => [], 'last_day' => '' ]
      )['result'];
    
    print_r($result);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search