Reputation: 22820
OK, here's the challenge I'm facing and it is quite a complicated one :
Example initial array :
Array
(
[0] => Array
(
[Title] => La science des rêves
[Year] => 2006
[Director] => Array
(
[Name] => Michel Gondry
[BirthYear] => 1963
[BirthPlace] => Versailles, Yvelines, France
)
)
[1] => Array
(
[Title] => Arizona Dream
[Year] => 1992
[Director] => Array
(
[Name] => Emir Kusturica
[BirthYear] => 1954
[BirthPlace] => Sarajevo, Bosnia and Herzegovina, Yugoslavia
)
)
)
Example allowed keys :
Array
(
[0] => Title
[1] => Director.Name
[2] => Director.BirthYear
)
I want to filter it so that the final array contains just the above keys (the numeric keys will be kept no-matter-what) :
Array
(
[0] => Array
(
[Title] => La science des rêves
[Director.Name] => Michel Gondry
[Director.BirthYear] => 1963
)
[1] => Array
(
[Title] => Arizona Dream
[Director.Name] => Emir Kusturica
[Director.BirthYear] => 1954
)
)
Any ideas on how to do this? I've been struggling for hours, with all sorts of recursive functions but I'm always seemingly missing something... :S
Upvotes: 1
Views: 214
Reputation: 4099
try this
$arr=Array
(
0 => Array
(
"Title" => "La science des rêves",
"Year" => "2006",
"Director" => Array
(
"Name" => "Michel Gondry",
"BirthYear" => "1963",
"BirthPlace" => "Versailles, Yvelines, France"
)
),
1 => Array
(
"Title" => "Arizona Dream",
"Year" => "1992",
"Director" => Array
(
"Name" => "Emir Kusturica",
"BirthYear" => "1954",
"BirthPlace" => "Sarajevo, Bosnia and Herzegovina, Yugoslavia"
)
)
);
$ck=Array
(
0 => "Title",
1 => "Director.Name",
2 => "Director.BirthYear"
);
$newarray=array(array());
$s=sizeof($arr);
$ss=0;
while($ss<$s)
{
foreach($ck as $ck2)
{
$k = explode(".",$ck2);
if(sizeof($k) > 1)
$newarray[$ss][$ck2]=$arr[$ss][$k[0]][$k[1]];
else
$newarray[$ss][$ck2]=$arr[$ss][$k[0]];
}$ss++;
}
print_r($newarray);
Upvotes: 1
Reputation: 4519
<?php
$array = array(Array(
"Title" => 'La science des rêves',
"Year" => '2006',
'Director' => Array
(
'Name' => 'Michel Gondry',
'BirthYear' => '1963',
'BirthPlace' => 'Versailles, Yvelines, France',
)
),
Array
(
'Title' => 'Arizona Dream',
'Year' => '1992',
'Director' => Array
(
'Name' => 'Emir Kusturica',
'BirthYear' => '1954',
'BirthPlace' => 'Sarajevo, Bosnia and Herzegovina, Yugoslavia'
)
)
);
/*
[Title] => La science des rêves
[Director.Name] => Michel Gondry
[Director.BirthYear] => 1963*/
echo '<pre>';
print_r($array);
echo '</pre>';
foreach($array as $final)
{
$final_array[] = array(
'title'=>$final['Title'],
'name'=>$final['Director']['Name'],
'birthyear'=> $final['Director']['BirthYear']
);
}
echo '<pre>';
print_r($final_array);
echo '</pre>';
Upvotes: 1
Reputation: 437386
First of all it's obvious you need a function that can flatten arbitrarily nested arrays. When you do this there's always the chance of key collisions if the input is engineered to produce them, but in your case that's not an issue so you would be OK with something like
function flatten($array, $separator = '.') {
foreach ($array as $key => $value) {
if (!is_array($value)) {
continue;
}
unset ($array[$key]);
foreach (flatten($value, $separator) as $subkey => $subval) {
$array[$key.$separator.$subkey] = $subval;
}
}
return $array;
}
You can now flatten each one of your "initial" rows with:
$flattened = array_map('flatten', $initial);
That leaves the problem of filtering out keys based on your whitelist, which you could do with
$whitelist = array_flip(['Title', 'Director.Name', /* etc */]);
$filter = function($array) use (&$whitelist) {
return array_intersect_key($array, $whitelist);
};
$filtered = array_map($filter, $flattened);
Upvotes: 1