簡體   English   中英

如何在PHP中創建遞歸函數以取消多維數組的設置?

[英]How to create a recursive function to unset multidimentional array in PHP?

下面是我的目標數組,我想根據候選數組元素通過鍵取消設置其元素。

$target = [
    60 => "Home"
    "Villa" => [
        "30" => "Vi",
    ],
    70 => "A",
    40 => "B",
    50 => "C",
    "Land" => [
        1 => "La",
        35 => "Lb",
        37 => "Lc",
        39 => "Ld",
    ],
];

$candidate = [30, 50, 35, 37];

以下是我取消設置后想要的結果。

$target = [
    60 => "Home"
    70 => "A",
    40 => "B",
    "Land" => [
        1 => "La",
        39 => "Ld",
    ],
];

還必須刪除'Villa',因為在其元素“ 30” =>“ Vi”設置為空之后,它為空。

下面我在for循環的解決方案。

foreach ($target as $id => $option) {
    if (isset($candidate[$id])) {
      unset($target[$id]);
    }
    elseif (is_array($option)) {
      foreach ($option as $sub_id => $opt) {
        if (isset($candidate[$sub_id])) {
          unset($target[$id][$sub_id]);
        }
      }
    }

    if (!count($target[$id])) {
      unset($target[$id]);
    }
}

如何在遞歸解決方案中替換此for循環?

function del($target, $candidate) {
    foreach ($target as $key => $value) {
        if (in_array($key, $candidate)) {
            unset($target[$key]);
        } elseif (is_array($value)) {
            $target[$key] = del($value, $candidate);
            if (!count($target[$key])) {
                unset($target[$key]);
            }
        }
    }
    return $target;
}

$new = del($target, $candidate);
var_dump($new);

這開始是對Mehdi的回答的評論,但我的空間有限:

盡管我相信數組是通過引用傳遞的,並且將引用分配給它來自的變量應該有最小的開銷,但令我驚訝的是,通過引用顯式傳遞可能更健壯和透明。

function clean(&$target, $candidate, $depth=0){
   if (++$depth>10) {
      // erk!
      trigger_error("Too deep!");
   }
   // Loop through candidates
   foreach($candidate as $index){
       // If the value is an array
       if(isset($target[$index]) && is_array($target[$index])){
           clean($target[$index], $candidate, $depth);
           if (!count($target[$index])) unset($target[$index]); // thanks jhilgeman
       } else {
           isset($target[$index]) && unset($target[$index]);
       }
   }
}

clean($target, $candidate);
var_dump($target);

編輯:

<?php
$target = [
    60 => "Home",
    "Villa" => [
        "30" => "Vi",
    ],
    70 => "A",
    40 => "B",
    50 => "C",
    "Land" => [
        1 => "La",
        35 => "Lb",
        37 => "Lc",
        39 => "Ld",
    ],
];

$candidate = [30, 50, 35, 37];

function clean(&$target, $candidate){
    // Loop through target
    foreach($target as $index => $value){
        // If the value is an array
        if(is_array($value)){
            // Clean it first
            $result = clean($value, $candidate);
            $target[$index] = $result;
        } else {
            // Check if the key is in the candidate array
            if(in_array($index, $candidate)){
                $target[$index] = NULL;
            }
        }
        // If the value is empty
        if(empty($target[$index])){
            // Unset it
            unset($target[$index]);
        }
    }
}

$target = clean($target, $candidate);

var_dump($target);

結果:

/var/www/test.php:47:
array (size=4)
  60 => string 'Home' (length=4)
  70 => string 'A' (length=1)
  40 => string 'B' (length=1)
  'Land' => 
    array (size=2)
      1 => string 'La' (length=2)
      39 => string 'Ld' (length=2)

正如提到的symcbean在這里使用引用會更好

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM