Home > Back-end >  Iterating through a one dimensional array and sorting it such that it becomes a two dimensional arra
Iterating through a one dimensional array and sorting it such that it becomes a two dimensional arra

Time:02-24

For example, is there a logical way for me to iterate through this one dimensional array;

Array
(
  [featured_video_video_type]       => array()
  [featured_video_video_mp4]        => array()
  [featured_video_video_webm]       => array()
  [featured_video_closed_captions]  => array()
  [featured_video]                  => array()
  [content]                         => array()
  [content_0_title]                 => array()
  [content_0_content]               => array()
  [content_1_quote]                 => array()
  [content_1_citation]              => array()
)

And matching the keys such that I turn it into the following two dimensional array?

Array
(
  [featured_video]  => array(
    [video] => array(
      [type] => array()
      [mp4]  => array()
      [webm] => array()
      [closed_captions]  => array()
    )
  )
  [content] => array(
    [0] => array(
      [title]   => array()
      [content] => array()
    )
    [1] => array(
      [title]   => array()
      [content] => array()
    )
)

I should add that it needs to work without knowing what keys will appear in the array. I can do it if I know the keys by just mapping the beginning of the array keys but totally dumbfounded as to how to do it otherwise.

EDIT: Adjusted video 2D array

CodePudding user response:

This looks like a really tough one. You could probably work through it with enough time, but I'm not sure how much time you have to devote to it. Here's how I would start:

<?php
function parse_the_array($array) {
    $keys = array_keys( $array );
    foreach( $keys as $i => $key ) {
        $key_words = explode('_', $key);
        $matches = 0;
        $j = $i;
        while(1) {
            $next_key = $keys[  $j];
            if ( ! empty( $next_key ) ) {
                $next_key_words = explode('_', $next_key);
                if ( $next_key_words[0] === $key_words[0] ) {
                    //The next key is a match, put it in an array of matching keys and increment matches
                    $matches  ;
                } else {
                    //The next key is not a match, break out
                    break;
                }
            } else {
                break;
            }
        }
        
        if ( $matches > 0 ) {
            // Now you have to compare all the matches and see how many words
            // they have in common to decide what the lowest level key is.
        }
    }
}

Like I said, it's a tough one. It would take a long time for me to get it right, and I'd have to know the constraints of what the keys could be. A simpler solution would be to break every underscore into a separate key so you have:

Array
(
    [featured] => array(
        [video]  => array(
            [video]  => array(
                [type] => array()
            )
            [video]  => array(
                [mp4]  => array()
            )
            [video]  => array(
                [webm] => array()
            )
            [closed]  => array(
                [captions]  => array()
            )
        )
    )
   ...
)

CodePudding user response:

Seemed like an interesting little problem, here is my attempt

I doubt it does everything you need, but should be enough to get you started

<?php

$rows = array(
    'featured_video_video_type' => array(),
    'featured_video_video_mp4' => array(),
    'featured_video_video_webm' => array(),
    'featured_video_closed_captions' => array(),
    'featured_video' => array(),
    'content' => array(),
    'content_0_title' => array(),
    'content_0_content' => array(),
    'content_1_quote' => array(),
    'content_1_citation' => array(),
);


$prefixes = ['featured_video', 'content'];

$output = [];

foreach ($rows as $key => $val) {

    foreach ($prefixes as $prefix) {
        if ($key === $prefix) {
            // exact match, ignore
            continue;
        }

        if (strpos($key, $prefix) !== 0) {
            // doesn't match prefix, ignore
            continue;
        }

        $new_key = substr($key, strlen($prefix)); // remove prefix
        $new_key = ltrim($new_key, '_'); // remove any leading _

        // match on pattern like 0_text
        if (preg_match("/(\d )_(. )/", $new_key, $matches)) {
            $idx = $matches[1];
            $new_key = $matches[2];

            $output[$prefix][$idx][$new_key] = $val;
        }
        else {
            $output[$prefix][$new_key] = $val;
        }
    }

}

print_r($output);


Array
(
    [featured_video] => Array
        (
            [video_type] => Array
                (
                )

            [video_mp4] => Array
                (
                )

            [video_webm] => Array
                (
                )

            [closed_captions] => Array
                (
                )

        )

    [content] => Array
        (
            [0] => Array
                (
                    [title] => Array
                        (
                        )

                    [content] => Array
                        (
                        )

                )

            [1] => Array
                (
                    [quote] => Array
                        (
                        )

                    [citation] => Array
                        (
                        )

                )

        )

)
  • Related