Функциональные коллекции
Реализация функциональных коллекций, как в java-stream, scala-collections. Например: collection.map(modifier).filter(...).reduce(...).
Чтобы было lazy и оптимально: два последовательных фильтра схлапываются в один.
Проходные: map, filter, flatMap, zip, take. Терминальные: reduce, fold, forEach.
TBDL
Литература
- MIT 6.005 - Map Filter Reduce это конспект лекций из курса Массачусетского университета на тему функциоанльных комбинаторов.
- Cornell University CS31100 - Map and Fold это конспект лекции из курса университета Корнелл про map, filter, fold на языке hascell.
- Wiki: Ленивые вычисления
- Java streams API - документация API ленивых коллекций в java. Есть объяснение типов операций - intermediate и terminal.
- Scala collections API - документация про устройство старых коллекций в scala. Они не lazy, но видов операций там очень много.
Как должно работать
TBDL
from func_collections import Seq
s = Seq(1,2,3,4) \
.filter(lambda x: x % 2 == 0) \
.map(lambda x: x ** 2) \
.reduce(lambda acc, cur: acc+cur)
assert(s == 2**2 + 4**2)
Базовый набор функций
Map
Функция трансофрмации, применяемая над каждым элементом последовательнсти.
Filter
Функция фильтрации, то есть отсеивает элементы, если они не удовлетворяют условию предиката.
Fold
Функция свёртки последовательности в некоторое одно значение.
Foreach
Функция обхода всего списка.
ToList
Фактически это fold с подготовленной функцией свертки в лист.
Дополнительные функции
FlatMap
Seq(1,2,3,4).flat_map(lambda x: [x,x*2]).to_list == [1,2, 3,6, 4,8]
Take
Взять первые n элементов последовательности.
Drop
Пропустить первые n элементов последовательности.
TakeWhile
Брать элементы из последовательности до тех пор пока выполняется условие.
DropWhile
Пропускать элементы до тех пор пока выполняется условие.
Zip
s1 = Seq(1,2,3,4)
s2 = Seq(10,20,30,40)
s1.zip(s2).to_list == [(1,10), (2,20), (3,30), (4,40)]
Sliding
Скользящее окно размером n.
Find
Найти первый удовлетворяющий условию элемент списка.
Flatten
IsAny
Удовлетворяет ли хоть один элемент списка условию.
IsSome
GroupBy
Основная идея группировки - это предоставить возможность для последующей агрегации результатов. Агрегации могут быть следующими:
- подсчет количества элементов в группе
count - суммирование всех элементов -
sum - превращение в словарь, где ключи это списки -
collect - считать статистики
mean,std,medianи так далее - и.т.д.
Seq(1,1,2,3,3,4,3,4).group_by(lambda x: x).agg(count).to_dict == {1: 2, 2: 1, 3: 3, 4: 2}