Как приятно читать «чередующиеся» строки? - PullRequest
0 голосов
/ 27 августа 2018

У меня есть текстовый файл, который содержит строки, которые следуют альтернативному шаблону, например:

name: SomeName 
counterA: 0, counterB: 0, counterC: 0
name: SomeNameB 
counterA: 1, counterB: 2, counterC: 3
...

Я хочу написать простой парсер, который выталкивает SameName и счетчики от A до C в новый объект.

Таким образом, задача в основном состоит в том, чтобы обрабатывать всегда две строки вместе.

Я начал с этого кода:

fun readFileAsLinesUsingReadLines(fileName: String): List<String> = File(fileName).readLines()

fun main(args: Array<String>) {
    val lines = readFileAsLinesUsingReadLines("Whatever")
    for (i in (0 .. lines.size-1 step 2)) {
        println(lines[i]+lines[i+1])
    }
}

и да, это печатает

name: SomeName counterA: 0, counterB: 0, counterC: 0

, который я могу затем проанализировать.

Но я считаю, что использование (0 .. lines-size-1 step) не очень элегантно.

Существуют ли более элегантные или "более котлинские" способы получения этой информации?

Ответы [ 2 ]

0 голосов
/ 27 августа 2018

Другой способ:

(0 until lines.size).filter { it % 2 == 0 }.forEach { println(lines[it] + lines[it+1]) }

или как предпочитает Роланд:

lines.indices.filter { it % 2 == 0 }.forEach { println(lines[it] + lines[it+1]) }
0 голосов
/ 27 августа 2018

Используя useLines, вы можете прочитать строки как (ленивую) последовательность, а затем использовать chunked с лямбда-преобразованием для анализа и форматирования по своему усмотрению.:

val result = File("file.txt").useLines { lines ->
    lines.chunked(2) { (l1, l2) -> l1 + l2 }.toList()
}

result.forEach { println(it) }

Если по какой-то причине вы хотите сначала все передать в память, вы также можете использовать readLines со списочной версией chunked:

val result = File("file.txt").readLines().chunked(2) { (l1, l2) -> l1 + l2 }

result.forEach { println(it) }
...