2014-02-10 3 views
1

ОК, вот проблема я столкнулся, и это довольно сложный:Как фильтровать многомерный массив на основе разрешенных ключей

  • Я имею многомерный массив (это может быть просто массив или он может идти на несколько уровней)
  • У меня есть набор «разрешенных» ключей (также содержащих ключи «parent.child»)
  • В конечном массиве нам нужны только цифровые клавиши и разрешенные ключи , Все остальное нужно отбросить из финального стола.

Пример Первоначальный массив:

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 
       ) 

     ) 

) 

Пример разрешенные ключи:

Array 
(
    [0] => Title 
    [1] => Director.Name 
    [2] => Director.BirthYear 
) 

Я хочу, чтобы отфильтровать его так, чтобы конечный массив содержит только вышеуказанные клавиши (числовой ключи будут сохранены без учета того, что):

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

Любые идеи о том, как это сделать? Я изо всех сил боролся с часами, со всякими рекурсивными функциями, но мне всегда казалось что-то не хватает ...: S

ответ

1

Прежде всего, очевидно, что вам нужна функция, которая может сглаживать произвольно вложенные массивы. Когда вы сделаете это, всегда есть шанс ключевых столкновений, если вход сконструирован так, чтобы производить их, но в вашем случае это не проблема, так что вы бы хорошо с чем-то вроде

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

Теперь вы можете придавить каждую из ваша «начальная» строка с:

$flattened = array_map('flatten', $initial); 

Это оставляет проблему фильтрации ключей на основе белого списка, который вы могли бы сделать с

$whitelist = array_flip(['Title', 'Director.Name', /* etc */]); 

$filter = function($array) use (&$whitelist) { 
    return array_intersect_key($array, $whitelist); 
}; 

$filtered = array_map($filter, $flattened); 
+0

Впечатляет и сверхбыстрой. Что еще я могу сказать? Благодарю. Благодарю. Благодарю. :-) –

+0

@ Dr.Kameleon: Рад помочь. Посмотрите на функции, которые я использовал, у PHP много полезных строительных блоков. Построение решения не так сложно, как только вы узнаете, что они там. – Jon

+0

Я знаю о мощной библиотеке функций PHP и - хотя я ее ненавидят «визуально» - это одна из главных причин, по которой мне это нравится. Тем не менее, моя главная проблема здесь заключалась в том, что это ... команда 'unset', которая вызвала у меня в прошлом довольно странные проблемы, чтобы я боялся этого ... –

1
<?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>'; 
1

попробовать это

$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

Смежные вопросы