【问题标题】:How does one use `Recall()` to write a recursive function to recursively list directories in a given directory?如何使用 Recall() 编写递归函数来递归列出给定目录中的目录?
【发布时间】:2011-06-12 15:36:23
【问题描述】:

这个Question 询问列出当前目录中的目录(不是文件)。我在对其中一个答案的评论中指出,我们不能使用 dirlist.files 等函数的 recursive 参数递归地列出当前目录中的目录。

对此的明显解决方案是编写一个递归函数,该函数列出当前目录中的目录,依次在每个目录上调用自身,依此类推,添加到最后返回的目录的整体列表中递归。

Recall() 函数似乎是理想的候选者,但我从来没有真正了解过如何编写递归函数,每次调用时都会添加到最终输出。

如何修改此功能:

list.dirs <- function(path) {
    x <- dir(path, full.names = TRUE)
    dnames <- x[file_test("-d", x)]
    dnames
}

让它递归地遍历dnames 中的目录,将它找到的任何目录添加到在dnames 目录中找到的所有目录的列表中,等等...?

【问题讨论】:

  • 我认为我的主要问题并不是真正了解应该如何编写一个函数以在其自身上使用Recall
  • 要在递归函数中使用Recall,请调用Recall而不是函数的名称。
  • @hadley 谢谢,但我通过?Recall 做到了这一点。这是如何安排返回的对象并将它们组合起来,我不太了解。
  • 所以也许你的困惑不在于使用recall(这很简单),而是如何编写一般的递归函数(这真的很复杂)?
  • @hadley 是的,我认为你一针见血。我希望如果有人可以展示如何使用Recall 使list.dirs 函数递归,我会更好地了解它是如何工作的。我挣扎了很长一段时间试图想出一个递归版本。

标签: r recursion


【解决方案1】:

这是一种方法:

list.dirs <- function(path) {
     x <- dir(path, full.names = TRUE)
     dnames <- x[file_test("-d", x)]
    tmp <- character(0)
    for(i in seq_along(dnames) ) {
        tmp <- c(tmp, Recall(dnames[i]) )
    }
     c(dnames,tmp)
 } 

这只是将子目录附加到末尾,可以使用一些不同的逻辑来给出不同的顺序。

【讨论】:

  • 谢谢格雷格。这实际上是我在通勤回家时想到的。我确定我在发帖之前已经尝试过,但如果我这样做了,那我就做错了,因为它失败了。
  • 在这个例子中,有一点不太清楚的是终端情况是什么——对于递归函数,清楚地标记基本情况通常是个好主意。在这个函数中,当length(dnamaes) == 0 时自然会发生,但我认为通过显式返回会很清楚。
  • @hadley 很好,我认为这是我最初出错的地方。尝试遵循?Recall 示例中的斐波那契序列函数,我看到有这样一个终端案例,并试图将其插入到我的尝试中。不过,我显然做错了,因为当我插入一些东西时,它就返回了!将在哪里插入终端盒检查,它会采用什么形式?会在循环开始之前插入if(length(dnames) == 0) return(tmp) 吗?
  • 是的,完全正确。没有它,如果你不知道seq_along 并且知道1:length(dnames),你也会遇到问题
猜你喜欢
  • 2020-08-19
  • 2013-10-26
  • 1970-01-01
  • 1970-01-01
  • 2013-07-01
  • 1970-01-01
  • 2016-07-11
  • 2015-09-12
  • 2011-11-14
相关资源
最近更新 更多