Helpers - компьютеры, интернет, программирование

Как изменить префикс последовательности Kotlin, но сохранить хвост?

Kotlin предоставляет методы take и takeWhile, которые позволяют брать первые n элементов Sequence<T> и обрабатывать их отдельно как другую последовательность, например, drop некоторые из них, map другие значения и т. д.

Но когда я использую take и takeWhile, хвост последовательности отбрасывается.

Теперь, учитывая однократно ограниченную последовательность, как мне преобразовать ее произвольный префикс в другую последовательность, сохраняющую хвост, если он остается?

Пример:

val seq = (1..10).asSequence().constrainOnce() 
// emits 1, 2, 3, 4, 5, 6, 7, 8, 9, 10

val modified = seq.changePrefix { take(5).map { -1 * it } }
// emits -1, -2, -3, -4, -5, 6, 7, 8, 9, 10

Как сделать то же самое для нескольких префиксов?

Пример:

val seq = (1..10).asSequence().constrainOnce()

val modified = seq.changePrefixes(
        { take(3).map { it * -1 } },
        { drop(1).take(3).map { it * 100 } },
        { map { 0 } }
)

//emits -1, -2, -3, 500, 600, 700, 0, 0, 0

Примечание. Вопрос задан намеренно и ответил автор.


Ответы:


1

Когда Sequence<T> однократно ограничено, это означает, что из него нельзя создать более одного Iterator. Поэтому решение состоит в том, чтобы создать один итератор и создать из него как измененный префикс, так и оставшийся хвост.

Метод Iterator<T> asSequence() оказывается полезным здесь, поскольку он создает последовательность, поддерживаемую итератором. Остается только соединить последовательности.

Вот как это сделать за одно изменение:

val seq = (1..10).asSequence().constrainOnce()
val modified = seq.iterator().let { iter -> 
    iter.asSequence().take(5).map { it * -1 } + iter.asSequence()
}

Обратите внимание, что две последовательности создаются из одного и того же итератора, но это нормально, потому что

  • Sequence оцениваются лениво
  • Две последовательности используются вместе и не просачиваются
  • Оценка второй последовательности в конкатенации начнется после завершения первой.

А вот как обобщить его на произвольное количество операторов последовательности:

fun <T> Sequence<T>.changePrefixes(vararg operators: Sequence<T>.() -> Sequence<T>)
: Sequence<T> {
    val i = iterator()
    return operators.fold(emptySequence<T>()) { acc, it -> acc + i.asSequence().it() } + 
            i.asSequence()
}

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

Ограничение этой реализации состоит в том, что когда оператор включает takeWhille, отклоненный элемент будет отброшен и не будет передан в следующую последовательность.

31.01.2016
Новые материалы

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

Использование машинного обучения для диагностики болезни Альцгеймера, часть 4
Маркеры семантической согласованности для ранней диагностики болезни Альцгеймера (arXiv) Автор: Давиде Колла , Маттео Дельсанто , Марко Агосто , Бенедетто Витиелло , Даниэле Паоло Радичони..

Почему объяснимость так важна прямо сейчас?
По мере того, как системы искусственного интеллекта и инструменты на основе машинного обучения распространяются в нашей повседневной жизни, как практики, так и критики все чаще заявляют о..

Анимированный математический анализ
Использование Manim для создания математических анимированных визуализаций Визуализация данных помогает понять скрытые закономерности в данных, которые невозможно визуализировать..

Создание простого слайдера изображений с помощью JavaScript
Узнайте, как создать базовый слайдер изображений с помощью HTML, CSS и JavaScript. Введение В этом уроке мы создадим удобный слайдер изображений, используя JavaScript, HTML и CSS. Ползунок..

Создание базы данных с помощью супергероя «Python»
В этом посте мы узнаем, как создать «базу данных SQLite с помощью модуля python sqlite3, создав простую функцию входа и регистрации. Готовы ли вы к этому путешествию? Если да , давайте приступим..

ИИ для чайников: руководство для начинающих по пониманию будущего технологий
Вы чувствуете, что остались позади в мире ИИ? Не волнуйтесь, вы не одиноки! Со всей этой шумихой вокруг искусственного интеллекта может быть трудно понять, с чего начать. Но не позволяйте сленгу..