2011-06-04 27 views
1

我需要從嵌套到另一個數組中的元素中取消設置元素,以便只保留第一個N元素(N被預定義)。只有具有數字索引的元素纔會受到影響。如何使用array_walk_recursive取消設置元素

輸入數組:

Array 
(
    [0] => Array (
     [a] => 'w' 
     [b] => Array (
      [0]=> 'x' 
      [1]=> 'x' 
      [2]=> 'x' 
     ) 
    )    
    [1] => Array (
     [a] => 'y' 
    ) 
    [2] => Array (
     [0] => 'z' 
     [1] => 'z' 
     [2] => 'z' 
    ) 
) 

希望的輸出(與N=2):

Array 
(
    [0] => Array (
     [a] => 'w' 
     [b] => Array (
      [0]=> 'x' 
      [1]=> 'x' 
     ) 
    )    
    [1] => Array (
     [a] => 'y' 
    ) 
) 

基於上述定義,只有[0][b][2][2]因爲他們有一個數值指標得到了未固化的和,因爲它們都再現了它們各自陣列的第三個元素。

+0

你想如何築巢?假設可以有10層嵌套,我是否正確?或者你的例子也是嵌套的最大數量?也許舉一個具體的例子來說明它的功能可以給你一個清晰的代碼圖像。 – Arend 2011-06-04 09:31:53

+0

嵌套層次沒有任何限制。可能有10個級別,可能會有更多,可能會更少,因此我最初的印象是,我可能不得不使用'array_walk_recursive'來完成這項工作,但是如果有更好的方法來等待更多的反饋信息。 – 2011-06-04 09:35:33

回答

1

寫一個你自己想要的功能。然後記錄這個函數,所以如果你需要在兩週內使用它,你可能想知道這個函數到底在做什麼。

我這樣說是因爲你想要處理的數據結構似乎非常具體。所以有必要將它封裝在一個函數中以隱藏複雜性。正確命名功能。

在函數內部,您可以用各種方式處理數據,並用各種條件來制定數據。來自外部的參數可以作爲函數參數傳遞。返回值是您想達到的結果。

5

尚未測試,但類似的東西可能工作。

function myFunc(&$array){ 
foreach($array as $key=>&$value){ 
if(is_array($value)){ 
    myFunc($value); 
} 
if(is_numeric($key) && $key > 1){ 
    unset($array[$key]); 
} 
} 
} 

關於array_walk。 php.net說:

程序員不能添加,取消設置或 重新排序元素。如果回調確實不符合此要求,則此功能的 行爲爲 未定義且不可預知。

+0

,它看起來不錯,用於取消設置特定數組的元素。現在我需要找到一種遞歸獲取數組的所有嵌套數組的方法。 – 2011-06-04 09:50:13

+1

我寫的函數是遞歸的。如果一個值是一個函數,它會遞歸地調用它自己。 – Headshota 2011-06-04 09:52:00

1

這工作對我來說,也許不是最乾淨的代碼。

$array = array 
(
    array(
     'a' => 'w', 
     'b' => array('x','x','x') 
    ), 
    array(
     'a' => 'y' 
    ), 
    array(
     'z','z','z' 
    ) 
); 

function recurse_and_strip ($array, &$size=2) 
{ 
    foreach ($array as $key => &$element) 
    { 
     if (is_hash($element)) 
     { 
      $element = recurse_and_strip($element,$size); 
     } else if (is_array($element)) 
     { 
      $deletefrom = false; 
      // now the tricky part.. see how many must be deleted 
      for ($i=0; $i < count($element); $i++) 
      { 
       if ($size == 0) 
       { 
        echo "Delete from " . $i; 
        $deletefrom = $i; 
        break 1; 
       } 
       $size--; 
      } 
      if ($deletefrom !== false) 
      { 
       if ($deletefrom == 0) 
       { 
        unset($array[$key]); 
       } else { 
        array_splice($element,$deletefrom); 
       } 
      } 
     } 
    } 
    return $array; 
} 

// source http://www.benjaminkeen.com/?p=23 
function is_hash($var) 
{ 
    if (!is_array($var)) 
    return false; 

    return array_keys($var) !== range(0,sizeof($var)-1); 
} 

var_dump(recurse_and_strip($array,2)); 
+0

適用於我,儘管我認爲你的'var_dump'行不正確,因爲'2'作爲var_dump'的參數給出,而不是'recurse_and_strip'。無論如何,謝謝你。 – 2011-06-04 12:10:22

+0

不幸的是,當測試一個具有3個嵌套層次的數組時,它不再工作。 – 2011-06-04 12:15:20

+0

你能告訴我你使用的例子嗎?在這裏也可以使用3個嵌套層次。另外,錯誤是什麼? – Arend 2011-06-04 14:13:39

1

array_walk_recursive本身不能達到你想要的。即使您可以通過引用傳遞數組,在回調中取消設置變量也只會在該範圍內取消設置。

但是,您可以使用walk_recursive_remove功能:

/** 
* http://uk1.php.net/array_walk_recursive implementation that is used to remove nodes from the array. 
* 
* @param array The input array. 
* @param callable $callback Function must return boolean value indicating whether to remove the node. 
* @return array 
*/ 
function walk_recursive_remove (array $array, callable $callback) { 
    foreach ($array as $k => $v) { 
     if (is_array($v)) { 
      $array[$k] = walk_recursive_remove($v, $callback); 
     } else { 
      if ($callback($v, $k)) { 
       unset($array[$k]); 
      } 
     } 
    } 

    return $array; 
} 

您需要使用$callback取消設置特定的值來實現自己的邏輯。

相關問題