Dr.Kameleon
Dr.Kameleon

Reputation: 22820

How to filter multi-dimensional array based on allowed keys

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

Answers (3)

krishna
krishna

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

Demo

Upvotes: 1

Dimag Kharab
Dimag Kharab

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

Jon
Jon

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

Related Questions