执行收集操作时,是否可以修改基础收集?

时间:2020-05-06 16:30:34

标签: kotlin collections

例如,我具有以下代码以递归方式复制目录的内容。

    private fun copyContentDirectory(directory : File): List<File> {
        val files = directory.listFiles().toList()
        val filesToTransform = mutableListOf<File>()

        // Add each file + directory. Then, recursively add the files in each directory.
        files
                .onEach  { filesToTransform += it }
                .filter  { it.isDirectory }
                .forEach { filesToTransform += copyContentDirectory(it) }

        return filesToTransform
    }

是否有可能出现以下情况?如果没有,为什么不呢?


    private fun copyContentDirectory(directory : File): List<File> {
        return directory.listFiles().toList()
                .filter  { it.isDirectory }
                .onEach  { <thisList> += copyContentDirectory(it) }
    }

thisList处的一些符号允许我引用基础列表。这样的东西存在吗?

1 个答案:

答案 0 :(得分:1)

根据评论,您的意图不是很清楚。

看第二个例子,显而易见的答案似乎是替换此行:

.onEach { <thisList> += copyContentDirectory(it) }

与一个使用flatMap()的人一起使用,例如:

.flatMap{ copyContentDirectory(it) }

它将所有递归调用的结果收集在一起,并将它们作为单个列表返回-我认为这就是您想要的。

但是,这只是揭示了更深层次的问题:

  • 尽管有名称,但该方法实际上并没有复制任何内容,只是收集了一个列表。
  • 列表将始终为空-遍历目录,但从不返回任何文件,因此,每个列表都将组合空列表。

这是一个解决第二个问题的版本。我还对其进行了重命名,将其重铸为扩展功能,并使用partition()避免了两次过滤。 (第一个结果是匹配谓词的文件,即目录在其上递归;第二个结果是不匹配的文件,即非目录,它直接包含在目录中。)而且因为listFiles()在某些情况下可以返回null ,它也必须处理。

private fun File.listContents(): List<File>
    = listFiles()
        ?.partition{ it.isDirectory }
        ?.let{ it.first.flatMap{ it.listContents() } + it.second }
        ?: listOf()

(这不能解决复制问题,但问题并不表示您打算如何处理。)

相关问题