Home » Php » php – Check nested Array values, if a match: combine data from both

php – Check nested Array values, if a match: combine data from both

Posted by: admin February 25, 2020 Leave a comment

Questions:

I have a weird situation, and I’m not totally sure if my solution is going to work, or is possible… It’s for a WordPress site, but I’m hoping it’s a general loop query as opposed to something specific to WP… but let’s try:

I have an array, something like this (changes as it’s looking up WP event posts):

$events = Array
(
[0] => WP_Post Object
    (
        [ID] => 8717
        [post_author] => 5
        [post_date] => 2020-01-28 14:25:36
        [post_parent] => 2766
        [post_title] => Film 1
    )
[1] => WP_Post Object
    (
        [ID] => 8716
        [post_author] => 5
        [post_date] => 2020-01-28 14:25:36
        [post_parent] => 2769
        [post_title] => Film 2
    )
[2] => WP_Post Object
    (
        [ID] => 8716
        [post_author] => 5
        [post_date] => 2020-01-28 14:25:39
        [post_parent] => 2766
        [post_title] => Film 1
    )
)

I loop through the array with a foreach:

foreach ( $events as $event ) { global $post; 
    echo tribe_event_featured_image( $event->ID, 'medium' );
    // This outputs an image, pulled from the event post

    echo '<h4>'. $event->post_title . '</h4>';

    tribe_get_start_date($event, false, $format= 'h:i')
    //This outputs a start time, pulled from the event
}

However, I need to first check if the post_parent is the same. If it is, rather than displaying those items separately, I need to display them together.

So the output currently is:

IMAGE
Film 1
10:00

IMAGE
Film 2
12:00

IMAGE 
Film 1
14:00

However, Film 1 and film 3 have the same “post_parent” key value, so I want the output to be:

IMAGE
Film 1
10:00, 14:00  (Note 14:00 is the time pulled from 3rd object in array)

IMAGE
Film 2
12:00
How to&Answers:

To achieve your desired results, you need filter the event times by their parent_post and skip over the events that were already displayed or check the post_parent to ensure it is not null or 0, which can be achieved by checking for empty($event->post_parent).

Additionally, you only need to declare global once, as foreach does not separate the variable scope.

Example: https://3v4l.org/pYjQJ

global $post;
$matchedParents = [];
foreach ($events as $event) { 
    if (in_array($event->ID, $matchedParents)) {
        /* post_parent has already been output, skip the event */
        continue;
    }

    echo tribe_event_featured_image($event->ID, 'medium');
    echo '<h4>'. $event->post_title . '</h4>';

    /* display the times based on post_parent */
    $eventTimes = [];
    if (empty($event->post_parent)) {
       /* ensure post_parent is not empty */
       $eventTimes[] = tribe_get_start_date($event, false, $format = 'h:i');
     } else {
        foreach ($events as $subEvent) {
           if ($event->post_parent === $subEvent->post_parent) {
            /* store the matched events */
               $matchedParents[] = $subEvent->ID;
            /* store the event times to be output later */
               $eventTimes[] = tribe_get_start_date($subEvent, false, $format = 'h:i');
           }
       }
    }
    /* optionally sort the times */
    natsort($eventTimes);

    /* output the event times as a CSV */
    echo implode(', ', $eventTimes);
}

Results

IMAGE
<h4>Film 1</h4>
10:00, 14:00

IMAGE
<h4>Film 2</h4>
14:25

IMAGE
<h4>Film 4</h4>
14:25

IMAGE
<h4>Film 5</h4>
14:00

Answer:

Check this answer. I did not test it but hope it works.

    $filtered_data = []; //An temp array
    // loop your array to create a new array with parent id as key
    foreach ( $events as $data ){
        $filtered_data[$data->post_parent][] = $data;
    }

    // loop the new array to display content as you desired
    foreach ( $filtered_data as $event_data ) { global $post; 
        echo tribe_event_featured_image( $event_data[0]->ID, 'medium' );
        // This outputs an image, pulled from the event post, since there can be multiple post ids, it takes first id to get the Image

        echo '<h4>'. $event_data[0]->post_title . '</h4>';  // same here, It will display first post title

// loop the sub array to get all the times
        foreach($event_data as $event) {
            echo  tribe_get_start_date($event, false, $format= 'h:i') . ',';
        }
        //This outputs a start time, pulled from the event
    }