0

Let's say I have an array like this:

array (
      0 =>
      array (
        'trip' => '1',
        'times' =>
        array (
          0 =>
          array (
            'order' => '1',
            'stop name' => 'Name 1',
            'stop time' => '7:03 am',
          ),
          1 =>
          array (
            'order' => '2',
            'stop name' => 'Name 2',
            'stop time' => '8:03 am',
          ),
          2 =>
          array (
            'order' => '3',
            'stop name' => 'Name 3',
            'stop time' => '9:03 am',
          ),
        ),
      ),
      1 =>
      array (
        'trip' => '2',
        'times' =>
        array (
          0 =>
          array (
            'order' => '1',
            'stop name' => 'Name 1',
            'stop time' => '10:03 am',
          ),
          1 =>
          array (
            'order' => '2',
            'stop name' => 'Name 3',
            'stop time' => '11:03 am',
          ),
        ),
      ),
      0 =>
      array (
        'trip' => '3',
        'times' =>
        array (
          0 =>
          array (
            'order' => '1',
            'stop name' => 'Name 1',
            'stop time' => '1:03 pm',
          ),
          1 =>
          array (
            'order' => '2',
            'stop name' => 'Name 2',
            'stop time' => '2:03 pm',
          ),
          2 =>
          array (
            'order' => '3',
            'stop name' => 'Name 3',
            'stop time' => '3:03 pm',
          ),
        ),
      ),
    )

But I want to transform this array via PHP into a table that looks like this:

Name 1    | Name 2   | Name 3
------------------------------
7:03am    | 8:03am   | 9:03am
------------------------------
10:03am   |          | 11:03am
------------------------------
1:03pm    | 2:03pm   | 3:03pm

Basically, where there may be gaps based on the nested array's data. I can already construct a table as if there would be no gaps, but that creates issues, and the data I'm using based off of a database doesn't allow gaps to be inserted, so I need to know if there is an easy way with php and array commands to construct a table like this where the row names can be remembered and filled if there is a value, or passed over if there is not.

3
  • Is it possible for Name 1 to be missing from trip #1 but present in trip #2? Commented Dec 6, 2018 at 16:52
  • yes it is possible Commented Dec 6, 2018 at 16:54
  • Oh OK, I think I have a solution. Hang tight Commented Dec 6, 2018 at 17:00

2 Answers 2

2

Since you can have random gaps (trips with/without certain names), you need to first figure out all of the unique names and fill them in as a blank per trip which they are not in.

Data

$a = array (
  0 =>
  array (
    'trip' => '1',
    'times' =>
    array (
      0 =>
      array (
        'order' => '1',
        'stop name' => 'Name 1',
        'stop time' => '7:03 am',
      ),
      1 =>
      array (
        'order' => '2',
        'stop name' => 'Name 2',
        'stop time' => '8:03 am',
      ),
      2 =>
      array (
        'order' => '3',
        'stop name' => 'Name 3',
        'stop time' => '9:03 am',
      ),
    ),
  ),
  1 =>
  array (
    'trip' => '2',
    'times' =>
    array (
      0 =>
      array (
        'order' => '1',
        'stop name' => 'Name 1',
        'stop time' => '10:03 am',
      ),
      1 =>
      array (
        'order' => '2',
        'stop name' => 'Name 3',
        'stop time' => '11:03 am',
      ),
    ),
  ),
  2 =>
  array (
    'trip' => '3',
    'times' =>
    array (
      0 =>
      array (
        'order' => '1',
        'stop name' => 'Name 1',
        'stop time' => '1:03 pm',
      ),
      1 =>
      array (
        'order' => '2',
        'stop name' => 'Name 2',
        'stop time' => '2:03 pm',
      ),
      2 => // Fixed this to 2 instead of 0 from your example
      array (
        'order' => '3',
        'stop name' => 'Name 3',
        'stop time' => '3:03 pm',
      ),
    ),
  ),
);

Code

// Get a listing of all unique names available in this multi-dimensional array
// We need this to figure out how many gaps there may be in the data per trip
$unique_names = array();
foreach( $a as $v )
{
    foreach( $v[ 'times' ] as $v2 )
    {
        $unique_names[ $v2[ 'stop name' ] ] = $v2[ 'stop name' ];
    }
}

// Create a listing of trips and contain all available names within it even if that name did not have an entry
$trips = array();
foreach( $a as $v )
{
    // Per trip hold the stops in the same order as the $unique_names which were encountered
    $trips[ $v[ 'trip' ] ] = array();

    // Per name add a trip stop
    foreach( $unique_names as $name )
    {
        $in_trip = false;

        // Loop the available stops and check if this name is a stop
        foreach( $v[ 'times' ] as $v3 )
        {
            if( $v3[ 'stop name' ] === $name )
            {
                $trips[ $v[ 'trip' ] ][] = $v3[ 'stop time' ];
                $in_trip = true;
                break;
            }
        }

        // This name was not a stop so it will get an empty entry
        if( !$in_trip )
        {
            $trips[ $v[ 'trip' ] ][] = '';
        }
    }
}


// Show the names
echo '<table><tr>';
foreach( $unique_names as $name )
{
    echo '<td>'.$name.'</td>';
}
echo '</tr>';

// Loop the trips and output their stop times
// The stop times should be in the same order as $unique_names
foreach( $trips as $trip )
{
    echo '<tr>';
    foreach( $trip as $time )
    {
        echo '<td>'.$time.'</td>';
    }
    echo '</tr>';
}
echo '</table>';

Output

Name 1    Name 2   Name 3
7:03 am   8:03 am  9:03 am
10:03 am           11:03 am
1:03 pm   2:03 pm  3:03 pm

enter image description here

Sign up to request clarification or add additional context in comments.

5 Comments

@Sammitch 98% of my being wanted VTC this post but the other 2% wanted to prove to myself that I can solve this problem if I ever encounter it. I guess that 2% has been working out and overpowered the 98%. Overall, OP at least provided good source data and an explicit example of desired output.
What does VTC stand for here?
@Sammitch Vote to Close
I apologize if my question was out of line with the usual questions on Stack Overflow. My main interest was to know if PHP had a function in it's library to handle this type of data issue. Thank you for all your help.
@Benlov Don't sweat it. If your question was truly off-topic then it would have been closed by now by other users. Stack Overflow 10 years old now and there have been huge fluctuations in regards to acceptable questions. Overall, it's an interesting real-world challenge but seeing an attempt is generally favorable. The over-arching answer is "There is no dedicated function for handling this specific issue; you have to use loops and logic."
2

Here is another solution, however as MonkeyZeus pointed; the first and last both keys in your array is 0. So with modified array.

$array = array (
          0 =>
          array (
            'trip' => '1',
            'times' =>
            array (
              0 =>
              array (
                'order' => '1',
                'stop name' => 'Name 1',
                'stop time' => '7:03 am',
              ),
              1 =>
              array (
                'order' => '2',
                'stop name' => 'Name 2',
                'stop time' => '8:03 am',
              ),
              2 =>
              array (
                'order' => '3',
                'stop name' => 'Name 3',
                'stop time' => '9:03 am',
              ),
            ),
          ),
          1 =>
          array (
            'trip' => '2',
            'times' =>
            array (
              0 =>
              array (
                'order' => '1',
                'stop name' => 'Name 1',
                'stop time' => '10:03 am',
              ),
              2 =>
              array (
                'order' => '2',
                'stop name' => 'Name 3',
                'stop time' => '11:03 am',
              ),
            ),
          ),
          2 =>
          array (
            'trip' => '3',
            'times' =>
            array (
              0 =>
              array (
                'order' => '1',
                'stop name' => 'Name 1',
                'stop time' => '1:03 pm',
              ),
              1 =>
              array (
                'order' => '2',
                'stop name' => 'Name 2',
                'stop time' => '2:03 pm',
              ),
              2 =>
              array (
                'order' => '3',
                'stop name' => 'Name 3',
                'stop time' => '3:03 pm',
              ),
            ),
          ),
        );

foreach ($array as $trow) {
            ?>
        <tr>
            <?php

            $count = 0;

            for ($i=0; $i <= count($trow['times']) ; $i++) { 
                if ($count == $i) {
                    ?>
                    <td><?= $trow['times'][$count]['stop time']; ?></td>
                    <?php
                } else {
                    ?>
                    <td></td>
                    <?php
                }
                $count++;
            }


            ?>
        </tr>
            <?php
            }

1 Comment

I gotta be honest, I do not fully understand your code and it is impressive. One slight improvement would be to use <td><?= (isset($trow['times'][$count]['stop time']) ? $trow['times'][$count]['stop time'] : ''); ?></td> to avoid undefined index errors.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.