Хорошо, вот одно предложение: partition
ваш список на элементы, которые содержат "bar" и элементы, которые не имеют.Возьмите первую коллекцию и замените соответствующие элементы (также подсчитайте их), а затем добавьте обратно другие элементы (не содержащие "bar").
val a = listOf("foo bar", "foo bar baz", "bar", "bar")
var replaced = 0
val replacedList = a.partition { it.contains("bar") }.let {
it.first.map { it.replace("bar", "baz") }.also { replaced = it.size } +
it.second
}
println(replaced) //4
println(replacedList) //[foo baz, foo baz baz, baz, baz]
Вот что делает partition
:
inline fun <T> Iterable<T>.partition(
predicate: (T) -> Boolean
): Pair<List<T>, List<T>> (source)
Разбивает исходную коллекцию на пару списков, где первый список содержит элементы, для которых предикат дал истину, а второй список содержит элементы, для которых предикат дал ложь.
РЕДАКТИРОВАТЬ:
Если вы хотите посчитать общее количество вхождений "bar" вместо количества строк, содержащих "bar", будет работать следующее (с пустым в качестве единственного допустимого спаратора):
val replacedList = a.partition { it.contains("bar") }.let { partitions ->
partitions.first.map { it.replace("bar", "baz") }.also {
replaced = partitions.first.flatMap { it.split(" ") }.count { it.contains("bar") }
} + partitions.second
}