свернуть список int в список диапазонов в kotlin - PullRequest
0 голосов
/ 03 мая 2018

У меня есть список целых чисел, которые необходимо сжать в список диапазонов int без потери какой-либо информации (должен быть способ отменить эту операцию).

В настоящее время у меня есть:

val ints = listOf(8, 9, 45, 48, 49, 60, 61, 61, 62, 63, 3, 4, 5, 4, 5, 6)
val out = ints
        .map { it..it }
        .fold(mutableListOf(ints[0]..(ints[0] - 1)),
                { acc, next ->
                    val prev = acc.last()
                    if (prev.last + 1 == next.first) {
                        acc[acc.lastIndex] = prev.first..next.last
                    } else {
                        acc.add(next)
                    }
                    acc
                }).toList()

Что правильно выдает:

[8..9, 45..45, 48..49, 60..61, 61..63, 3..5, 4..6]

В моем решении есть два аспекта, которые мне не нравятся,

  1. не работает для пустого списка из-за начального значения сгиба

  2. это довольно многословно для котлина. У меня такое ощущение, что это можно решить немного более приятным способом.

Итак, вопрос в том, как исправить 1 и / или 2?

Заранее спасибо!

Ответы [ 2 ]

0 голосов
/ 03 мая 2018

Поскольку вы действительно изменяете acc и возвращаете один и тот же список диапазонов на всех итерациях fold, вам может не понадобиться fold, то есть достаточно forEach.

Тогда отображение каждого числа на it..it представляется здесь избыточным.

Принимая во внимание два приведенных выше замечания, мы получаем несколько упрощенную версию вашего решения:

val result = mutableListOf<IntRange>()
ints.forEach {
    val lastRange = result.lastOrNull()
    if (lastRange?.endInclusive == it - 1)
        result[result.lastIndex] = lastRange.first..it
    else
        result += it..it
}
0 голосов
/ 03 мая 2018

Мое решение выглядит немного иначе, но я смог решить проблему с пустым списком:

val out = ints.fold(mutableListOf<IntRange>()) { acc, next ->
    acc.apply {
        if(isNotEmpty() && last().endInclusive.inc() == next) {
            this[lastIndex] = this[lastIndex].start .. next
        } else {
            add(next..next)
        }
    }
}

Это также немного меньше отображения, и применение apply устраняет некоторые детали и необходимость ссылаться на acc в конце.

...