Команда ReQL: fold
Синтаксис команды
sequence.fold(base, function) → value sequence.fold(base, function, emit=function[, final_emit=function]) → sequence
Описание
Применяет функцию к последовательности элементов по порядку, сохраняя состояние через накопитель. Команда fold возвращает либо одно значение, либо новую последовательность.
В первом варианте fold работает так же, как reduce, возвращая значение, применяя комбинирующую функцию к каждому элементу последовательности. Комбинирующая функция принимает два параметра: предыдущий результат сокращения (накопитель) и текущий элемент. Однако fold имеет следующие отличия от reduce:
- гарантируется обработка последовательности от первого элемента к последнему.
- передает начальное базовое значение функции вместе с первым элементом вместо предыдущего результата сокращения.
combining_function(accumulator | base, element) → new_accumulator
Во втором варианте fold работает подобно concat_map, возвращая новую последовательность вместо единственного значения. Если предоставлена функция emit, fold будет:
- обрабатывать последовательность по порядку и использовать начальное базовое значение, как описано выше.
- для каждого элемента в последовательности вызывать как комбинирующую функцию, так и отдельную функцию вывода. Функция вывода принимает три параметра: предыдущий результат сокращения (накопитель), текущий элемент и результат из комбинирующей функции (новое значение накопителя).
Если предоставлена функция вывода, она должна возвращать список.
emit(previous_accumulator, element, accumulator) → array
Также может быть предоставлена функция, которая будет вызвана в конце последовательности. Она принимает один параметр: результат последнего сокращения (накопитель) или исходное базовое значение, если входная последовательность была пустой. Эта функция должна вернуть список, который будет добавлен к выходному потоку fold.
final_emit(accumulator | base) → array
Пример: Объединить слова из списка.
r.table('words').order_by('id').fold('',
lambda acc, word: acc + r.branch(acc == '', '', ', ') + word
).run(conn)
(Этот пример можно реализовать с помощью reduce, но fold сохранит порядок, когда words — это таблица RethinkDB или другой поток, что не гарантируется reduce.)
Пример: Возвратить каждую вторую строку в таблице.
r.table('even_things').fold(0,
lambda acc, row: acc + 1,
emit=lambda acc, row, new_acc: r.branch((new_acc % 2 == 0), [row], [])
).run(conn)
Первая функция увеличивает накопитель каждый раз при вызове, начиная с 0; вторая функция, функция вывода, чередует возвращение списка, содержащего текущую строку, или пустого списка. Команда fold вернёт конкатенированный список каждого выведенного значения.
Пример: Вычислить среднее значение за пять дней для трекера веса.
r.table('tracker').filter({'name': 'bob'}).order_by('date')['weight'].fold(
[],
lambda acc, row: ([row] + acc).limit(5),
emit=lambda acc, row, new_acc: r.branch(new_acc.size() == 5, [new_acc.avg()], [])
).run(conn)
© RethinkDB contributors
Licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License.
https://rethinkdb.com/api/python/fold/