используйте 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 }