Функциональный способ генерации имен файлов в Scala - PullRequest
4 голосов
/ 26 апреля 2019

Хорошо, я хочу создать временные имена файлов. Итак, я создал класс с var tempFileName и fileNo таким, что он создает файлы типа

BSirCN_0.txt
BSirCN_1.txt
BSirCN_2.txt

Но, чтобы сделать это, я должен вести подсчет и то, как я это делаю, вызывает функцию класса next(), которая возвращает имя файла в последовательности (должна возвращать BSirCN_4 в приведенном выше случае. Теперь это противоречит FP, поскольку я изменяю состояние, то есть количество имен в Объекте. Как мне сделать это функциональным способом. Один из способов, который я могу придумать, - это вести подсчет, где функция вызывается и просто объединяется. Любые другие способы?

Ответы [ 3 ]

6 голосов
/ 26 апреля 2019

Просто верните новый объект:

case class FileGenerator(tempFileName: String, fileNo: Long = 0) {
  lazy val currentFileName = tempFileName + "_" + fileNo
  lazy val next = FileGenerator(tempFileName, fileNo + 1)
}

Вы можете сделать:

val generator = FileGenerator("BSirCN")

val first = generator.currentFileName
val next = generator.next.currentFileName
5 голосов
/ 26 апреля 2019

Вы можете избежать мутаций, используя Итератор (или любой другой вид бесконечной и ленивой коллекции) .

final class TempFileNamesGenerator(prefix: String) {
  private[this] val generator =
    Iterator
      .from(start = 0)
      .map(i => s"${prefix}_${i}.txt")

  def next(): String =
    generator.next()
}

val generator = new TempFileNamesGenerator(prefix = "BSirCN")

generator.next() // BSirCN_0.txt
generator.next() // BSirCN_1.txt
generator.next() // BSirCN_2.txt
4 голосов
/ 26 апреля 2019

Решение, аналогичное предложенному @Luis, но с использованием потоков:

def namesStream(prefix: String, suffix: String): Stream[String] = Stream.from(0).map(n => s"$prefix$n$suffix")

Затем используйте его следующим образом:

val stream = namesStream("BSirCN_", ".txt")
stream.take(5) // BSirCN_1.txt, BSirCN_2.txt, BSirCN_3.txt, BSirCN_4.txt, BSirCN_5.txt
// or
stream.drop(10).take(2) // BSirCN_11.txt, BSirCN_12.txt
...