Функции для работы со списками
- ListCreate
- AsList и AsListStrict
- ListLength
- ListHasItems
- ListCollect
- ListSort, ListSortAsc и ListSortDesc
- ListExtend и ListExtendStrict
- ListUnionAll
- ListZip и ListZipAll
- ListEnumerate
- ListReverse
- ListSkip
- ListTake
- ListIndexOf
- ListMap, ListFlatMap и ListFilter
- ListNotNull
- ListFlatten
- ListUniq
- ListAny и ListAll
- ListHas
- ListHead, ListLast
- ListMin, ListMax, ListSum и ListAvg
- ListFold, ListFold1
- ListFoldMap, ListFold1Map
- ListFromRange
- ListReplicate
- ListConcat
- ListExtract
- ListTakeWhile, ListSkipWhile
- ListAggregate
- ToDict и ToMultiDict
- ToSet
ListCreate
Сконструировать пустой список. В единственном аргументе указывается строка с описанием типа данных ячейки списка, либо сам тип, полученный с помощью предназначенных для этого функций. Списков с неизвестным типом ячейки в YQL не бывает.
Документация по формату описания типа.
Примеры
SELECT ListCreate(Tuple<String,Double?>);
SELECT ListCreate(OptionalType(DataType("String")));
Сигнатура
ListCreate(T)->List<T>
AsList и AsListStrict
Сконструировать список из одного или более аргументов. Типы аргументов должны быть совместимы в случае AsList
и строго совпадать в случае AsListStrict
.
Примеры
SELECT AsList(1, 2, 3, 4, 5);
Сигнатура
AsList(T..)->List<T>
ListLength
Количество элементов в списке.
Сигнатура
ListLength(List<T>)->Uint64
ListLength(List<T>?)->Uint64?
ListHasItems
Проверка того, что список содержит хотя бы один элемент.
Сигнатура
ListHasItems(List<T>)->Bool
ListHasItems(List<T>?)->Bool?
ListCollect
Преобразовать ленивый список (строится, например, функциями ListFilter, ListMap, ListFlatMap) в энергичный. В отличие от ленивого списка, в котором каждый повторный проход заново вычисляет его содержимое, в энергичном списке содержимое списка строится сразу ценой большего потребления памяти.
Сигнатура
ListCollect(LazyList<T>)->List<T>
ListCollect(LazyList<T>?)->List<T>?
ListSort, ListSortAsc и ListSortDesc
Отсортировать список. По умолчанию выполняется сортировка по возрастанию (ListSort
— алиас к ListSortAsc
).
Аргументы:
- Список;
- Опциональное выражение для получения ключа сортировки из элемента списка (по умолчанию сам элемент).
Примеры
$list = AsList(
AsTuple("x", 3),
AsTuple("xx", 1),
AsTuple("a", 2)
);
SELECT ListSort($list, ($x) -> {
RETURN $x.1;
});
Примечание
В примере использовалась лямбда функция.
Сигнатура
ListSort(List<T>)->List<T>
ListSort(List<T>?)->List<T>?
ListSort(List<T>, (T)->U)->List<T>
ListSort(List<T>?, (T)->U)->List<T>?
ListExtend и ListExtendStrict
Последовательно соединить списки (конкатенация списков). В качестве аргументов могут быть списки, опциональные списки и NULL
.
Типы элементов списков должны быть совместимы в случае ListExtend
и строго совпадать в случае ListExtendStrict
.
Если хотя бы один из списков является опциональным, то таким же является и результат.
Если хотя бы один аргумент является NULL
, то тип результата - NULL
.
Примеры
$l1 = AsList("a", "b");
$l2 = AsList("b", "c");
$l3 = AsList("d", "e");
SELECT ListExtend($l1, $l2, $l3); -- ["a","b","b","c","d","e"]
Сигнатура
ListExtend(List<T>..)->List<T>
ListExtend(List<T>?..)->List<T>?
ListUnionAll
Последовательно соединить списки структур (конкатенация списков). В выходном списке структур будет присутствовать поле, если оно есть хотя бы в одном исходном списке, при этом в случае отсутствия такого поля в каком-либо списке оно дополняется как NULL. В случае, когда поле присутствует в двух и более списках, поле в результате приводит в общий тип.
Если хотя бы один из списков является опциональным, то таким же является и результат.
Примеры
$l1 = AsList(
<|value:1|>,
<|value:2|>
);
$l2 = AsList(
<|key:"a"|>,
<|key:"b"|>
);
SELECT ListUnionAll($l1, $l2); -- result: [("value":1),("value":2),("key":"a"),("key":"b")]
-- schema: List<Struct<key : String?, value : Int32?>>
Сигнатура
ListUnionAll(List<Struct<..>>, List<Struct<..>>..)->List<Struct<..>>
ListUnionAll(List<Struct<..>>?, List<Struct<..>>?..)->List<Struct<..>>?
ListZip и ListZipAll
По входящим спискам построить список пар, содержащих соответствующие по индексу элементы списков (List<Tuple<first_list_element_type,second_list_element_type>>
).
Длина возвращаемого списка определяется самым коротким списком для ListZip и самым длинным — для ListZipAll.
Когда более короткий список исчерпан, в качестве пары к элементам более длинного списка подставляется пустое значение (NULL
) соответствующего optional типа.
Примеры
$l1 = AsList("a", "b");
$l2 = AsList(1, 2, 3);
SELECT ListZip($l1, $l2); -- [("a",1),("b",2)]
SELECT ListZipAll($l1, $l2); -- [("a",1),("b",2),(null,3)]
Сигнатура
ListZip(List<T1>, List<T2>)->List<Tuple<T1, T2>>
ListZip(List<T1>?, List<T2>?)->List<Tuple<T1, T2>>?
ListZipAll(List<T1>, List<T2>)->List<Tuple<T1?, T2?>>
ListZipAll(List<T1>?, List<T2>?)->List<Tuple<T1?, T2?>>?
ListEnumerate
Построить список пар (Tuple), содержащих номер элемента и сам элемент (List<Tuple<Uint64,list_element_type>>
).
Сигнатура
ListEnumerate(List<T>)->List<Tuple<Uint64, T>>
ListEnumerate(List<T>?)->List<Tuple<Uint64, T>>?
ListReverse
Развернуть список.
Сигнатура
ListReverse(List<T>)->List<T>
ListReverse(List<T>?)->List<T>?
ListSkip
Возвращает копию списка с пропущенным указанным числом первых элементов.
Первый аргумент — исходный список, второй — сколько элементов пропустить.
Примеры
$l1 = AsList(1, 2, 3, 4, 5);
SELECT ListSkip($l1, 2); -- [3,4,5]
Сигнатура
ListSkip(List<T>, Uint64)->List<T>
ListSkip(List<T>?, Uint64)->List<T>?
ListTake
Возвращает копию списка, состоящую из ограниченного числа элементов второго списка.
Первый аргумент — исходный список, второй — не больше скольких элементов с начала оставить.
Примеры
$l1 = AsList(1, 2, 3, 4, 5);
SELECT ListTake($l1, 2); -- [1,2]
Сигнатура
ListTake(List<T>, Uint64)->List<T>
ListTake(List<T>?, Uint64)->List<T>?
ListIndexOf
Ищет элемент с указанным значением в списке и при первом обнаружении возвращает его индекс. Отсчет индексов начинается с 0, а в случае отсутствия элемента возвращается NULL
.
Примеры
$l1 = AsList(1, 2, 3, 4, 5);
SELECT ListIndexOf($l1, 2); -- 1
Сигнатура
ListIndexOf(List<T>, T)->Uint64?
ListIndexOf(List<T>?, T)->Uint64?
ListMap, ListFlatMap и ListFilter
Применяют к каждому элементу списка указанную в качестве второго аргумента функцию. Различаются возвращаемым результатом:
ListMap
— возвращает список с результатами;ListFlatMap
— возвращает список с результатами, объединяя и разворачивая первый уровень результатов (списков или опциональных значений) по каждому элементу;ListFilter
— оставляет только те элементы, для которых функция вернулаtrue
.
Примечание
В ListFlatMap
использование опциональных значений в результатах функции является устаревшим, вместо этого следует использовать комбинацию ListNotNull
и ListMap
.
Аргументы:
- Исходный список;
- Функции для обработки элементов, например:
- Лямбда функция;
Module::Function
- С++ UDF;
Если исходный список является опциональным, то таким же является и выходной список.
Примеры
$list = AsList("a", "b", "c");
$filter = ($x) -> {
RETURN $x == "b";
};
SELECT ListFilter($list, $filter); -- ["b"]
$list = AsList(1,2,3,4);
$callable = Python::test(Callable<(Int64)->Bool>, "def test(i): return i % 2");
SELECT ListFilter($list, $callable); -- [1,3]
Сигнатура
ListMap(List<T>, (T)->U)->List<U>
ListMap(List<T>?, (T)->U)->List<U>?
ListFlatMap(List<T>, (T)->List<U>)->List<U>
ListFlatMap(List<T>?, (T)->List<U>)->List<U>?
ListFlatMap(List<T>, (T)->U?)->List<U>
ListFlatMap(List<T>?, (T)->U?)->List<U>?
ListFilter(List<T>, (T)->Bool)->List<T>
ListFilter(List<T>?, (T)->Bool)->List<T>?
ListNotNull
Применяет трансформацию исходного списка, пропуская пустые опциональные элементы, и усиливает тип элемента до неопционального. Для списка с неопциональными элементами возвращает исходный список без изменений.
Если исходный список является опциональным, то таким же является и выходной список.
Примеры
SELECT ListNotNull([1,2]), -- [1,2]
ListNotNull([3,null,4]); -- [3,4]
Сигнатура
ListNotNull(List<T?>)->List<T>
ListNotNull(List<T?>?)->List<T>?
ListFlatten
Разворачивает список списков в плоский список с сохранением порядка элементов. В качестве элемента списка верхнего уровня поддерживается опциональный список, который интерпретируется как пустой в случае NULL
.
Если исходный список является опциональным, то таким же является и выходной список.
Примеры
SELECT ListFlatten([[1,2],[3,4]]), -- [1,2,3,4]
ListFlatten([null,[3,4],[5,6]]); -- [3,4,5,6]
Сигнатура
ListFlatten(List<List<T>?>)->List<T>
ListFlatten(List<List<T>?>?)->List<T>?
ListUniq
Возвращает копию списка, в котором оставлен только уникальный набор элементов.
Сигнатура
ListUniq(List<T>)->List<T>
ListUniq(List<T>?)->List<T>?
ListAny и ListAll
Для списка булевых значений возвращает true
, если:
ListAny
— хотя бы один элемент равенtrue
;ListAll
— все элементы равныtrue
.
В противном случае возвращает false.
Сигнатура
ListAny(List<Bool>)->Bool
ListAny(List<Bool>?)->Bool?
ListAll(List<Bool>)->Bool
ListAll(List<Bool>?)->Bool?
ListHas
Содержит ли список указанный элемент.
Примеры
$l1 = AsList(1, 2, 3, 4, 5);
SELECT ListHas($l1, 2); -- true
SELECT ListHas($l1, 6); -- false
Сигнатура
ListHas(List<T>, T)->Bool
ListHas(List<T>?, T)->Bool?
ListHead, ListLast
Возвращают первый и последний элемент списка.
Сигнатура
ListHead(List<T>)->T?
ListHead(List<T>?)->T?
ListLast(List<T>)->T?
ListLast(List<T>?)->T?
ListMin, ListMax, ListSum и ListAvg
Применяет соответствующую агрегатную функцию ко всем элементам списка числовых значений.
Сигнатура
ListMin(List<T>)->T?
ListMin(List<T>?)->T?
ListFold, ListFold1
Свёртка списка.
Аргументы:
- Список
- Начальное состояние U для ListFold, initLambda(item:T)->U для ListFold1
- updateLambda(item:T, state:U)->U
Возвращаемый тип:
U для ListFold, опциональный U для ListFold1.
Примеры
$l = [1, 4, 7, 2];
$y = ($x, $y) -> { RETURN $x + $y; };
$z = ($x) -> { RETURN 4 * $x; };
SELECT
ListFold($l, 6, $y) AS fold, -- 20
ListFold([], 3, $y) AS fold_empty, -- 3
ListFold1($l, $z, $y) AS fold1, -- 17
ListFold1([], $z, $y) AS fold1_empty; -- Null
Сигнатура
ListFold(List<T>, U, (T, U)->U)->U
ListFold(List<T>?, U, (T, U)->U)->U?
ListFold1(List<T>, (T)->U, (T, U)->U)->U?
ListFold1(List<T>?, (T)->U, (T, U)->U)->U?
ListFoldMap, ListFold1Map
Преобразует каждый элемент i в списке путём вызова handler(i, state).
Аргументы:
- Список
- Начальное состояние S для ListFoldMap, initLambda(item:T)->кортеж (U S) для ListFold1Map
- handler(item:T, state:S)->кортеж (U S)
Возвращаемый тип:
Список элементов U.
Примеры
$l = [1, 4, 7, 2];
$x = ($i, $s) -> { RETURN ($i * $s, $i + $s); };
$t = ($i) -> { RETURN ($i + 1, $i + 2); };
SELECT
ListFoldMap([], 1, $x), -- []
ListFoldMap($l, 1, $x), -- [1, 8, 42, 26]
ListFold1Map([], $t, $x), -- []
ListFold1Map($l, $t, $x); -- [2, 12, 49, 28]
Сигнатура
ListFoldMap(List<T>, S, (T, S)->Tuple<U,S>)->List<U>
ListFoldMap(List<T>?, S, (T, S)->Tuple<U,S>)->List<U>?
ListFold1Map(List<T>, (T)->Tuple<U,S>, (T, S)->Tuple<U,S>)->List<U>
ListFold1Map(List<T>?, (T)->Tuple<U,S>, (T, S)->Tuple<U,S>)->List<U>?
ListFromRange
Генерация последовательности чисел или дат с указанным шагом. Аналог xrange
в Python 2, но дополнительно с поддержкой дат и чисел с плавающей точкой.
Аргументы:
- Начало
- Конец
- Шаг. Опционально, по умолчанию 1 для числовых последовательностей, 1 день для
Date
/TzDate
, 1 секунда дляDatetime
/TzDatetime
и 1 микросекунда дляTimestamp
/TzTimestamp
/Interval
Особенности:
- Конец не включительный, т.е.
ListFromRange(1,3) == AsList(1,2)
. - Тип элементов результатов выбирается как наиболее широкий из типов аргументов, например результатом
ListFromRange(1, 2, 0.5)
получится списокDouble
. - Если начало и конец имеют один из типов дат, то шаг должен иметь тип
Interval
. - Список является «ленивым», но при неправильном использовании всё равно может привести к потреблению большого объема оперативной памяти.
- Если шаг положительный и конец меньше или равен началу, то список будет пустой.
- Если шаг отрицательный и конец больше или равен началу, то список будет пустой.
- Если шаг не положительный и не отрицательный (0 или NaN), то список будет пустой.
- Если один из параметров опциональный, то результат будет опциональный список.
- Если один из параметров равен
NULL
, то результат будетNULL
.
Примеры
SELECT
ListFromRange(-2, 2), -- [-2, -1, 0, 1]
ListFromRange(2, 1, -0.5); -- [2.0, 1.5]
SELECT ListFromRange(Datetime("2022-05-23T15:30:00Z"), Datetime("2022-05-30T15:30:00Z"), DateTime::IntervalFromDays(1));
Сигнатура
ListFromRange(T, T)->LazyList<T> -- T - числовой тип или тип, представляющий дату/время
ListReplicate
Создает список из нескольких копий указанного значения.
Обязательные аргументы:
- Значение;
- Число копий.
Примеры
SELECT ListReplicate(true, 3); -- [true, true, true]
Сигнатура
ListReplicate(T, Uint64)->List<T>
ListConcat
Объединяет список строк в одну строку.
Вторым параметром можно задать разделитель.
Примеры
$l1 = AsList("h", "e", "l", "l", "o");
SELECT ListConcat($l1); -- "hello"
SELECT ListConcat($l1, " "); -- "h e l l o"
Сигнатура
ListConcat(List<String>)->String?
ListConcat(List<String>?)->String?
ListConcat(List<String>, String)->String?
ListConcat(List<String>?, String)->String?
ListExtract
По списку структур возвращает список содержащихся в них полей с указанным именем.
Примеры
$l = AsList(
<|key:"a", value:1|>,
<|key:"b", value:2|>
);
SELECT ListExtract($l, "key"); -- ["a", "b"]
Сигнатура
ListExtract(List<Struct<..>>, String)->List<T>
ListExtract(List<Struct<..>>?, String)->List<T>?
ListTakeWhile, ListSkipWhile
ListTakeWhile
выдает список от начала, пока предикат истинный, далее список заканчивается.
ListSkipWhile
пропускает отрезок списка от начала, пока предикат истинный, далее выдает остаток список не обращая внимания на предикат.
ListTakeWhileInclusive
выдает список от начала, пока предикат истинный, далее список заканчивается, но также включает элемент, на котором сработал останавливающий предикат.
ListSkipWhileInclusive
пропускает отрезок списка от начала, пока предикат истинный, далее выдает остаток список не обращая внимания на предикат, но не включая элемент, на котором сработал предикат, а начинает со следующего за ним.
Обязательные аргументы:
- Список;
- Предикат.
Если входной список является опциональным, то таким же является и результат.
Примеры
$data = AsList(1, 2, 5, 1, 2, 7);
SELECT
ListTakeWhile($data, ($x) -> {return $x <= 3}), -- [1, 2]
ListSkipWhile($data, ($x) -> {return $x <= 3}), -- [5, 1, 2, 7]
ListTakeWhileInclusive($data, ($x) -> {return $x <= 3}), -- [1, 2, 5]
ListSkipWhileInclusive($data, ($x) -> {return $x <= 3}); -- [1, 2, 7]
Сигнатура
ListTakeWhile(List<T>, (T)->Bool)->List<T>
ListTakeWhile(List<T>?, (T)->Bool)->List<T>?
ListAggregate
Применить фабрику агрегационных функций для переданного списка.
Если переданный список является пустым, то результат агрегации будет такой же, как для пустой таблицы: 0 для функции COUNT
и NULL
для других функций.
Если переданный список является опциональным и равен NULL
, то в результате также будет NULL
.
Аргументы:
- Список;
- Фабрика агрегационных функций.
Примеры
SELECT ListAggregate(AsList(1, 2, 3), AggregationFactory("Sum")); -- 6
Сигнатура
ListAggregate(List<T>, AggregationFactory)->T
ListAggregate(List<T>?, AggregationFactory)->T?
ToDict и ToMultiDict
Преобразуют список из кортежей с парами ключ-значение в словарь. В случае конфликтов по ключам во входном списке ToDict
оставляет первое значение, а ToMultiDict
— собирает из всех значений список.
Таким образом:
ToDict
изList<Tuple<K, V>>
делаетDict<K, V>
ToMultiDict
изList<Tuple<K, V>>
делаетDict<K, List<V>>
Также поддерживаются опциональные списки, что приводит к опциональному словарю в результате.
Примеры
$l = AsList(("a",1), ("b", 2), ("a", 3));
SELECT ToDict($l); -- {"a": 1,"b": 2}
Сигнатура
ToDict(List<Tuple<K,V>>)->Dict<K,V>
ToDict(List<Tuple<K,V>>?)->Dict<K,V>?
ToSet
Преобразует список в словарь, в котором ключи являются уникальными элементами этого списка, а значения отсутствуют и имеют тип Void
. Для списка List<T>
тип результата будет Dict<T, Void>
.
Также поддерживается опциональный список, что приводит к опциональному словарю в результате.
Обратная функция - получить список ключей словаря DictKeys.
Примеры
$l = AsList(1,1,2,2,3);
SELECT ToSet($l); -- {1,2,3}
Сигнатура
ToSet(List<T>)->Set<T>
ToSet(List<T>?)->Set<T>?