簡體   English   中英

如何將這兩個遞歸函數合二為一?

[英]How can I merge this two recursive functions into one?

我想將這兩個函數合二為一,因為我想要一個更具可讀性的代碼,但我找不到解決方案。 你能幫我嗎?

function setTplArray_fn($data) {
   $array = [];
   if (!is_array($data)) {
       return htmlspecialchars($data);
   }
   else {
       foreach ($data as $key => $value) {
           $array[htmlspecialchars($key)] = setTplArray_fn($value);
       }
   }

   return $array;
}

function setTplArray($key, $data) {
   global $tplArray;

   $tplArray[$key] = setTplArray_fn($data);
}

將執行單個操作的代碼塊提取到專用函數中是編程中非常常見的最佳實踐。 此外,沒有專用函數的遞歸確實會使代碼更難閱讀,至少在我(以及我遇到的每個人)看來。

如果您想讓您的代碼更具可讀性,請添加一些注釋和類型提示,稍微重新組織代碼,並以清晰的方式命名。

例如,雖然我不太了解你的代碼庫,但我會像這樣重寫你的函數:

/**
 * @param array|string $data
 * @return array|string
 */
function sanitizeTplValues($data) {
    // If passed a string, just sanitize it normally
    if (!is_array($data)) {
        return htmlspecialchars($data);
    }

    // If passed an array, sanitize both the key and the values
    // NOTE: The value sanitization recursively calls this same function
    $array = [];
    foreach ($data as $key => $value) {
        $array[htmlspecialchars($key)] = sanitizeTplValues($value);
    }

    return $array;
}
  • 在頂部,我添加了幾乎所有現代 IDE 都支持的DocBlock標簽。 描述在這里也是一個好主意,但我會把它留給你。
  • 我重命名了該函數以更好地符合(我認為)它的作用
  • 通常,實際上並不需要else ,這里就是這種情況。 我們可以早點return ,我們的大腦可以假設一旦我們通過了第一個if ,我們就可以保證有一個數組
  • 我將數組聲明移到第一個塊下方,因為它沒有在那里使用
  • 我添加了注釋,盡管有人認為代碼“足夠明顯”
  • 我在代碼中明確調用了遞歸。 我個人更喜歡用NOTE:語法來做到這一點,盡管有些人認為注釋中的注釋很奇怪。

調用代碼只是略有變化,上面的一些應用到了它:

/**
 * @param string $key
 * @param array|string $data
 */
function setTplArray(string $key, $data) {
    global $tplArray;

    $tplArray[$key] = sanitizeTplValues($data);
}

我所做的所有更改都是基於行業標准建議以及我自己的個人喜好的組合。 它們在任何方面都不是絕對的,您可以選擇適合您的方法。

我寫了很多遞歸代碼,你必須盡早決定的一件事是“這應該是一個函數還是兩個函數”,並且 99% 的時間我推薦兩個函數。 如果你只有一個,你的代碼必須弄清楚如何引導自己。 這通常是通過可選的空參數、深度檢查或魔術值來完成的,所有這些都只是在自找麻煩。 如果您可以讓一個函數為您執行引導邏輯,而另一個函數始終是 100% 遞歸的,那么它就是一個明確的關注點分離並且更容易維護。

暫無
暫無

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

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