Добавить условие для ограничения joinToString в Kotlin - PullRequest
0 голосов
/ 25 декабря 2018

У меня есть список таких строк:

val texts = listOf("It is a",
                "long established fact that a reader will be distracted,",
                "by the readable content of a page when looking at its layout.",
                "The point of using Lorem Ipsum is that it has a more-or-less normal",
                "distribution of letters, as opposed to using, making it look like readable English.",
                " Many desktop publishing packages and web page,",
                "editors now use Lorem Ipsum as their default model text, and a search,",
                "for \'lorem ipsum\' will uncover many web sites still in their infancy",
                "Various versions have evolved over the years", ...)

Я хочу добавить разделитель "" между ними и ограничить длину результата.

Используя joinToString и subString, я могу добиться результата.

texts.filter { it.isNotBlank() }
                .joinToString(separator = " ")
                .substring()

Вопрос: я хочу использовать только joinToString и прерывать итератор всякий раз, когда он достигает MAX_LENGTH так что он не должен делать никаких "соединений" и subString после этого.

Как я мог это сделать?

Ответы [ 2 ]

0 голосов
/ 25 декабря 2018

Сначала используйте takeWhile для ограничения общей длины, а затем join:

fun main(args: Array<String>) {
    val texts = listOf("It is a",
            "long established fact that a reader will be distracted,",
            "by the readable content of a page when looking at its layout.",
            "The point of using Lorem Ipsum is that it has a more-or-less normal",
            "distribution of letters, as opposed to using, making it look like readable English.",
            " Many desktop publishing packages and web page,",
            "editors now use Lorem Ipsum as their default model text, and a search,",
            "for \'lorem ipsum\' will uncover many web sites still in their infancy",
            "Various versions have evolved over the years")

    val limit = 130
    var sum = 0
    val str = texts.takeWhile { sum += it.length + 1;  sum <= limit }.joinToString(" ")

    println(str)
    println(str.length)
}

напечатает

It is a long established fact that a reader will be distracted, by the readable content of a page when looking at its layout.
125
0 голосов
/ 25 декабря 2018

используйте limit параметр в joinToString

val substring = texts.filter { it.isNotBlank() }
                .joinToString(separator = " ", limit = 10, truncated = "")
                .substring(0)

Примечание * Параметр truncated, чтобы избежать суффикса ....

Поскольку исходный ответ ищет MAX_LENGTH в качестве окончательной строкиДлина выше решения не будет работать.Идеальным является takeWhile, как в принятом ответе.Но для этого нужно полагаться на внешние переменные.Я бы предпочел использовать функциональный подход, если бы мог, но, похоже, его нет.Так что в основном нам нужно уменьшить операцию с предикатом, поэтому немного измененная версия reduce будет работать

public inline fun <S, T : S> Iterable<T>.reduceWithPredicate(operation: (acc: S, T) -> S, predicate: (S) -> Boolean): S {
        val iterator = this.iterator()
        if (!iterator.hasNext()) throw UnsupportedOperationException("Empty collection can't be reduced.")
        var accumulator: S = iterator.next()
        while (iterator.hasNext() && predicate(accumulator)) {
            accumulator = operation(accumulator, iterator.next())
        }
        return accumulator
    }

Поскольку мы имеем дело с конкатенацией строк и пытаемся ограничить ее длиной, мы должны использовать substringчтобы получить точную длину, но указанная выше встроенная функция уничтожает объединение всех элементов и не требует промежуточного списка, как в takeWhile.Также битовая версия takeWhile будет работать

val joinedString = texts.filter { it.isNotBlank() }
                .reduceWithPredicate({ s1, s2 -> "$s1 $s2" }, { it.length < 100 })
                .substring(100)
assertTrue { joinedString.length < 100 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...