2010-09-30 138 views
0
$foo = array(
    '1' => '2', 
    '3' => array(
     '4' => '5' 
    ), 
    '6' => array(
     '7' => '8', 
     '9' => '10', 
     '11' => array(
      '12' => '13', 
      '14' => '15' 
     ) 
    ) 
); 

$bar = array(
    '1', 
    '6' => array(
     '7', 
     '11' => array(
      '12' 
     ) 
    ) 
); 

Foo是一個數組,我必須編輯,Bar編輯我需要做的。如何將某些數組元素「合併」到同一數組的元素中?

我必須在包含Bar中指向的元素的Foo數組中創建另一個元素,並從Foo中刪除原件。

因此,與陣列,最終陣列應該是:

Array(
    '3' => array(
     '4' => '5' 
    ), 
    '6' => array(
     '9' => '10', 
     '11' => array(
      '14' => '15' 
     ) 
    ), 
    'merged' => array(
     '1' => '2', 
     '6' => array(
      '7' => '8', 
      '11' => array(
       '12' => '13' 
      ) 
     ) 
    ) 
) 

我已經建立這個遞歸函數,但只適用於該陣列的第一層次:

foreach($bar AS $key => $value){ 
    if(is_array($value)){ 
     s($foo, $key, $value); 
    }else{ 
     $foo['merged'][$value] = $foo[$value]; 
     unset($foo[$value]); 
    } 
} 


function s(&$form, $key, $value){ 
    if(is_array($value)){ 
     foreach($value AS $k => $v){ 
      s($form, $k, $v); 
     } 
    }else{ 
     $form['merged'][$value] = $form[$value]; 
     unset($foo[$value]); 
    } 
} 

任何想法?

回答

1

您的腳本目前最大的問題是,您認爲沒有密鑰的元素是獨立的構造。數組$酒吧實際上看起來像這樣到PHP:

$bar = array(
    '0' => '1', 
    '6' => array(
     '0' => '7', 
     '11' => array(
      '0' => '12' 
     ) 
    ) 
) 

認識到這一點,當你看到在$欄中的關鍵「0」很明顯我們應該看的價值並移動鍵=>值對到$ foo ['merged'],但當你看到'6'時它變得更加複雜。當你意識到你不能嵌套foreach()循環時更加複雜,因爲這個數組可能有無限的級別。

在任何抽象數據類型中處理任意數量級別的技巧是帶有靜態計數器(用於跟蹤級別)的遞歸函數。通過這種方式,我們可以繼續深入到$ bar中,但是當我們完成後,我們會退回到我們遺漏的位置。如果我們讓這個櫃檯成爲一個樂團,我們可以跟蹤我們如何到達現在的位置。這樣我們可以稍後在$ foo中找到元素。

/* recursive_foobar is the only function you call */ 

function recursive_foobar(&$foo, $bar, &$merged){ 
    static $counter; 
    if(is_empty($counter)){ // initialize counter the first time 
     $counter = array(); 
    } 
    foreach($bar as $key => $element){ 
     if(is_array($element)){ 
      $counter[] = $key; 
      recursive_foobar($foo, $element, $merged[$key]); 
     } else { 
      $old_value = recursive_get($foo, array_push($counter, $element)); 
      recursive_remove($foo, array_push($counter, $element)); 
      array_merge($merged, $old_value); 
     } 
    } 
    return $merged; 
} 

/* recursive_get returns a multi-level array containing the requested element at the lowest level */ 

function recursive_get($haystack, $key){ 
    static $return; 
    if(count($key) > 1){ 
     $return[] = array(recursive_get($haystack[$key[0]], array_shift($key))); 
    } else { 
     $return[] = $haystack[$key[0]]; 
    } 
    return $return; 
} 

/* recursive_remove will remove the requested element, leaving all containers untouched */ 

function recursive_remove(&$array, $key){ 
    if(count($key) > 1){ 
     recursive_remove($array[$key[0]], array_shift($key)); 
    } else { 
     remove($array[$key[0]]) ??? 
    } 
} 

$foo['merged'] = array(); 
recursive_foobar($foo, $bar, $foo['merged']); 

這是一種馬虎,但你要求涉及一些相當高級的構造和一些複雜的邏輯。可能有一些我沒有記住的PHP函數可以減少一些代碼,但是你正在討論的是從任意長度的任意長度和任意次數的數組中刪除任意元素......

相關問題