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
(
)
)
)
)