繁体   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