Spec-Zone.ru › RethinkDB javascript

Команда ReQL: fold

Синтаксис команды

sequence.fold(base, function) → value
sequence.fold(base, function, {emit: function[, finalEmit: function]}) → sequence

Описание

Применяет функцию к последовательности в порядке следования, сохраняя состояние через накопитель. Команда fold возвращает либо одно значение, либо новую последовательность.

В первом варианте fold работает как reduce, возвращая значение, применяя комбинирующую функцию к каждому элементу в последовательности. Комбинирующая функция принимает два параметра: предыдущий результат сокращения (накопитель) и текущий элемент. Однако fold имеет следующие отличия от reduce:

  • гарантируется проход по последовательности от первого элемента к последнему.
  • передает начальное базовое значение в функцию вместе с первым элементом вместо предыдущего результата сокращения.
combiningFunction(accumulator | base, element) → newAccumulator

Во втором варианте fold работает как concatMap, возвращая новую последовательность вместо одного значения. При предоставлении функции emit fold будет:

  • проходить по последовательности в порядке и принимать начальное базовое значение, как указано выше.
  • для каждого элемента в последовательности вызывать как комбинирующую функцию, так и отдельную функцию вывода. Функция вывода принимает три параметра: предыдущий результат сокращения (накопитель), текущий элемент и результат из комбинирующей функции (новое значение накопителя).

Если функция вывода предоставлена, она должна возвращать список.

emit(previousAccumulator, element, accumulator) → array

Также может быть предоставлена функция finalEmit, которая будет вызвана в конце последовательности. Она принимает один параметр: результат последнего сокращения во время итерации (накопитель) или исходное базовое значение, если входная последовательность была пустой. Эта функция должна возвращать список, который будет добавлен к выходному потоку fold.

finalEmit(accumulator | base) → array

Пример: Объединить слова из списка.

r.table('words').orderBy('id').fold('', function (acc, word) {
    return acc.add(r.branch(acc.eq(''), '', ', ')).add(word);
}).run(conn, callback);

(Этот пример можно реализовать с помощью reduce, но fold сохранит порядок, когда words — это таблица RethinkDB или другой поток, что не гарантируется с reduce.)

Пример: Возвратить каждую вторую строку в таблице.

r.table('even_things').fold(0, function(acc, row) {
    return acc.add(1);
}, {emit:
    function (acc, row, new_acc) {
        return r.branch(new_acc.mod(2).eq(0), [row], []);
    }
}).run(conn, callback);

Первая функция инкрементирует накопитель каждый раз при вызове, начиная с 0; вторая функция, функция вывода, поочередно возвращает список, содержащий текущую строку, или пустой список. Команда fold вернёт объединённый список каждого выведенного значения.

Пример: Вычисление пятидневной скользящей средней для трекера веса.

r.table('tracker').filter({name: 'bob'}).orderBy('date')('weight').fold(
    [],
    function (acc, row) { return r.expr([row]).add(acc).limit(5); },
    {emit:
        function (acc, row, newAcc) {
            return r.branch(newAcc.length().eq(5), [newAcc.avg()], []);
        }
    }
).run(conn, callback);

Связанные команды

  • reduce
  • concatMap

© RethinkDB contributors
Licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License.
https://rethinkdb.com/api/javascript/fold/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API