fweigl
fweigl

Reputation: 22008

Collect iterables into one variable (list)

Consider this:

  fun readFiles(directory: String): List<File> {
    val result = ArrayList<File>()

    File(directory).walkTopDown().forEach {
      result.addAll(getFiles(it))
    }

    return result
  }

  fun getFiles(file: File): List<File> { ... }

How can rewrite this so I don't need to initialize the result ArrayList but can directly return File(directory).walkTopDown().????

The question is not about what's the best way to read files or anything, just how I can write the above code more concise while doing the same.

Upvotes: 0

Views: 76

Answers (1)

marstran
marstran

Reputation: 27971

You can use flatMap for this purpose. It first maps each element to a Sequence using your mapping function (so you kinda get a Sequence<Sequence<File>>), then it flattens every result back to a Sequence<File>.

Since walkTopDown returns a FileTreeWalk (which is a subclass of Sequence<File>), and you return a List<File>, you have to do some conversions as well. You can remove these conversions if you make getFiles and readFiles return a Sequence<File> instead.

fun readFiles(directory: String): List<File> {
    return File(directory)
              .walkTopDown()
              .flatMap { getFiles(it).asSequence() }
              .toList()
}

Upvotes: 2

Related Questions