SparkSql数组操作的N种骚气用法

2022-11-25 19:39:29 浏览数 (1)

最近业务侧花样提需求,里面涉及到了各种数组的切片、合并、去重、拼接、压平等操作,本来以为需要自己开发很多udf才可以,后来扒了一下源码,发现这些用法sparksql已经帮我们实现了呀~~

太了不起了,我承认是我见识短了,所以就有了这篇......

总结一下sparksql(基于branch3.3) 中 array操作相关的骚气用法,这恐怕是总结的最全的一篇了,哈哈~~

从源码里看到,array相关函数主要分为四类:

  • array_funcs(一般的array函数,比如取最大、最小、包含、切片等)
  • collection_funcs(集合类的操作,比如数组求size、反转、拼接等)
  • map_funcs(从map结构中衍生出来的函数,比如element_at)
  • lambda_funcs(这几种函数中当属lambda_funcs最骚气,学起来会比较难,但可真是太灵活了,能帮我们解决很多实现上的问题)

需要注意的点:

  • 1、array_funcs、collection_funcs、map_funcs都是支持全代码生成的,而lambda_funcs不支持全代码生成,所以在使用lambda_funcs时,需要注意效率问题
  • 2、如果看功能描述看不太明白,可以多看看案例,一看案例就什么都明白了
  • 3、在真正使用时,要测试一下对null的兼容性,有的函数对null做了兼容,有的函数没有做,使用前测一下最保险。对于遇到null会抛出异常的函数,我们需要对null提前做一下兼容处理

array_funcs

array

对应的类:CreateArray

功能描述:用sql创建一个数组(原来生成一个数组这么简单,我之前经常用split('1,2,3',',')这种形式来生成数组,现在看来用array函数最方便快捷)

版本:1.1.0

是否支持全代码生成:支持

用法:

代码语言:javascript复制
--生成一维数组
select array(1, 3, 5) as arr;
 --------- 
|arr      |
 --------- 
|[1, 3, 5]|
 --------- 

--生成二维数组
select array(array(1, 2, 3), array(1, 3, 5)) as arr;
 ---------------------- 
|arr                   |
 ---------------------- 
|[[1, 2, 3], [1, 3, 5]]|
 ---------------------- 

array_contains

对应的类:ArrayContains

功能描述:判断数组是不是包含某个元素,如果包含返回true(这个比较常用)

版本:1.5.0

是否支持全代码生成:支持

用法:

代码语言:javascript复制
--包含
select array_contains(array(1, 2, 3), 2) as is_contains;
 ----------- 
|is_contains|
 ----------- 
|true       |
 ----------- 

--不包含
select array_contains(array(1, 2, 3), 5) as is_contains;
 ----------- 
|is_contains|
 ----------- 
|false      |
 ----------- 

arrays_overlap

对应的类:ArraysOverlap

功能描述:

1、两个数组是否有非空元素重叠,如果有返回true

2、如果两个数组的元素都非空,且没有重叠,返回false

3、如果两个数组的元素有空,且没有非空元素重叠,返回null

版本:2.4.0

是否支持全代码生成:支持

用法:

代码语言:javascript复制
--两个数组不存在null元素,且有重叠元素,返回true
select arrays_overlap(array(1, 2, 3), array(3, 4, 5)) as is_overlap;
 ---------- 
|is_overlap|
 ---------- 
|true      |
 ---------- 

--两个数组其中有一个存在null元素,且有重叠元素,返回true
select arrays_overlap(array(1, 2, 3), array(null, 2, 6)) as is_overlap;
 ---------- 
|is_overlap|
 ---------- 
|true      |
 ---------- 

--两个数组都存在null元素,且有重叠元素,返回true
select arrays_overlap(array(1, 2, null), array(null, 2, 6)) as is_overlap;
 ---------- 
|is_overlap|
 ---------- 
|true      |
 ---------- 

--两个数组都不存在null元素,且无重叠元素,返回false
select arrays_overlap(array(1, 2, 3), array(4, 5, 6)) as is_overlap;
 ---------- 
|is_overlap|
 ---------- 
|false     |
 ---------- 

--两个数组其中有一个存在null元素,且无重叠元素,返回null
select arrays_overlap(array(1, 2, 3), array(null, 5, 6)) as is_overlap;
 ---------- 
|is_overlap|
 ---------- 
|null      |
 ---------- 

--两个数组都存在null元素,且无重叠元素,返回null
select arrays_overlap(array(1, 2, null), array(null, 5, 6)) as is_overlap;
 ---------- 
|is_overlap|
 ---------- 
|null      |
 ---------- 

array_intersect

对应的类:ArrayIntersect

功能描述:返回两个数组相交的元素数组,并且不重复

版本:2.4.0

是否支持全代码生成:支持

用法:

代码语言:javascript复制
--正常情况的案例
select array_intersect(array(1, 2, 3), array(1, 3, 5)) as intersect_arr;
 ------------- 
|intersect_arr|
 ------------- 
|[1, 3]       |
 ------------- 

--有重复且有null的案例
select array_intersect(array(1, 2, 3, 3, null), array(1, 3, 5, null)) as intersect_arr;
 ------------- 
|intersect_arr|
 ------------- 
|[1, 3, null] |
 ------------- 

array_join

对应的类:ArrayJoin

功能描述:

用给定的分隔符和可选字符串替换null,来连接给定数组的元素;如果未设置【可选字符串替换null】,会过滤null值

从代码的构造函数也能看出,我们可以选择输入array(数组), delimiter(分隔符)这两个参数,也可以输入 array(数组), delimiter(分隔符),nullReplacement(如果数组中有null的,替换null的字符串,如果不输入,则默认把null过滤掉)这三个参数

版本:2.4.0

是否支持全代码生成:支持

用法:

代码语言:javascript复制
--数组里没有null元素,且分隔符为逗号
select array_join(array('hello', 'world'), ',') as join_str;
 ----------- 
|join_str   |
 ----------- 
|hello,world|
 ----------- 

--数组里有null元素,且分隔符为逗号,且不输入【可选字符串替换null】,可以看到null元素被过滤
select array_join(array('hello', null ,'world'), ',') as join_str;
 ----------- 
|join_str   |
 ----------- 
|hello,world|
 ----------- 

--数组里有null元素,且分隔符为逗号,且将null替换为  
select array_join(array('hello', null ,'world'), ',', '  ') as join_str;
 -------------- 
|join_str      |
 -------------- 
|hello,  ,world|
 -------------- 

array_position

对应的类:ArrayPosition

功能描述:返回给定数组中元素第一次出现的位置(索引从1开始)

1、如果在数组中找不到给定值,则返回0

2、如果任一参数为null,则返回null

版本:2.4.0

是否支持全代码生成:支持

用法:

代码语言:javascript复制
--正常情况的案例
select array_position(array(3, 2, 1), 1) as pos;
 --- 
|pos|
 --- 
|3  |
 --- 

--找不到,返回0
select array_position(array(3, 2, 1), 5) as pos;
 --- 
|pos|
 --- 
|0  |
 --- 

--返回null
select array_position(array(3, 2, 1), null) as pos;
 ---- 
|pos |
 ---- 
|null|
 ---- 

array_except

对应的类:ArrayExcept

功能描述:返回在array1中但不在array2中的元素数组,去重

版本:2.4.0

是否支持全代码生成:支持

用法:

代码语言:javascript复制
--array1数组里没有null元素
select array_except(array(1, 2, 2, 3), array(1, 3, 5)) as except_arr;
 ---------- 
|except_arr|
 ---------- 
|[2]       |
 ---------- 

--array1数组里有null元素
select array_except(array(1, 2, 2, null, 3), array(1, 3, 5)) as except_arr;
 ---------- 
|except_arr|
 ---------- 
|[2, null] |
 ---------- 

array_union

对应的类:ArrayUnion

功能描述:返回array1和array2并集中的元素数组,去重

版本:2.4.0

是否支持全代码生成:支持

用法:

代码语言:javascript复制
select array_union(array(1, 2, 2, 3), array(1, 3, 5,null)) as union_arr;
 ------------------ 
|union_arr         |
 ------------------ 
|[1, 2, 3, 5, null]|
 ------------------ 

slice

对应的类:Slice

功能描述:slice(x, start, length) --从索引开始(数组索引从1开始,如果开始为负,则从结尾开始)获取指定长度length的数组x的子集;如果取长度length超出数组长度,取能取出的最大的长度(挺好用,我们业务侧经常要求取某次搜索下N个商品)

版本:2.4.0

是否支持全代码生成:支持

用法:

代码语言:javascript复制
--取从第2位开始,长度为2
select slice(array(1, 2, 3, 4), 2, 2) as slice_arr;
 --------- 
|slice_arr|
 --------- 
|[2, 3]   |
 --------- 

--取从倒数第2位开始,长度为2
select slice(array(1, 2, 3, 4), -2, 2) as slice_arr;
 --------- 
|slice_arr|
 --------- 
|[3, 4]   |
 --------- 

--取从倒数第2位开始,长度为20(长度超限制,取能取出的最大的长度)
select slice(array(1, 2, 3, 4), -2, 20) as slice_arr;
 --------- 
|slice_arr|
 --------- 
|[3, 4]   |
 --------- 

arrays_zip

对应的类:ArraysZip

功能描述:arrays_zip(a1,a2,…)-返回结构的合并数组,其中第N个结构包含输入数组的所有第N个值(合并数组中有null数组,整体返回null)

版本:2.4.0

是否支持全代码生成:支持

用法:

代码语言:javascript复制
--2个数组,无null元素与数组
select arrays_zip(array(1, 2, 3), array(2, 3, 4)) as zip;
 ------------------------ 
|zip                     |
 ------------------------ 
|[{1, 2}, {2, 3}, {3, 4}]|
 ------------------------ 

--3个数组,无null元素与数组
select arrays_zip(array(1, 2), array(2, 3), array(3, 4)) as zip;
 ---------------------- 
|zip                   |
 ---------------------- 
|[{1, 2, 3}, {2, 3, 4}]|
 ---------------------- 

--3个数组,有null元素
select arrays_zip(array(1, 2), array(2, 3), array(3, null)) as zip;
 ------------------------- 
|zip                      |
 ------------------------- 
|[{1, 2, 3}, {2, 3, null}]|
 ------------------------- 

--有null数组,整体返回null
select arrays_zip(array(1, 2), array(2, 3), null) as zip;
 ---- 
|zip |
 ---- 
|null|
 ---- 

sort_array

对应的类:SortArray

功能描述:sort_array(array[,ascendingOrder])--根据数组元素的自然顺序,按升序或降序对输入数组排序

1、对于双/浮点类型,NaN大于任何非NaN元素

2、Null元素将按升序放置在返回数组的开头,或按降序放置在返回数组的末尾

版本:1.5.0

是否支持全代码生成:支持

用法:

代码语言:javascript复制
--升序
select sort_array(array('b', 'd', null, 'c', 'a'), true) as sort_arr;
 ------------------ 
|sort_arr          |
 ------------------ 
|[null, a, b, c, d]|
 ------------------ 

--降序
select sort_array(array('b', 'd', null, 'c', 'a'), false) as sort_arr;
 ------------------ 
|sort_arr          |
 ------------------ 
|[d, c, b, a, null]|
 ------------------ 

--null
select sort_array(null, true) as sort_arr;
 -------- 
|sort_arr|
 -------- 
|null    |
 -------- 

shuffle

对应的类:Shuffle

功能描述:把给定数组的元素重新洗牌

版本:2.4.0

是否支持全代码生成:支持

用法:

代码语言:javascript复制
--没null元素
select shuffle(array(1, 20, 3, 5)) as shuffle_arr;
 ------------- 
|shuffle_arr  |
 ------------- 
|[5, 3, 1, 20]|
 ------------- 

--有null元素
select shuffle(array(1, 20, null, 3)) as shuffle_arr;
 ---------------- 
|shuffle_arr     |
 ---------------- 
|[20, null, 3, 1]|
 ---------------- 

--null
select shuffle(null) as shuffle_arr;
 ----------- 
|shuffle_arr|
 ----------- 
|null       |
 ----------- 

array_min

对应的类:ArrayMin

功能描述:返回数组中的最小值

1、对于双/浮点类型,NaN大于任何非NaN元素

2、跳过空值

版本:2.4.0

是否支持全代码生成:支持

用法:

代码语言:javascript复制
--正常案例
select array_min(array(1, 20, null, 3)) as min_arr;
 ------- 
|min_arr|
 ------- 
|1      |
 ------- 

--空数组
select array_min(null) as min_arr;
 ------- 
|min_arr|
 ------- 
|null   |
 ------- 

array_max

对应的类:ArrayMax

功能描述:返回数组中的最大值

1、对于双/浮点类型,NaN大于任何非NaN元素

2、跳过空值

版本:2.4.0

是否支持全代码生成:支持

用法:

代码语言:javascript复制
--正常案例
select array_max(array(1, 20, null, 3)) as max_arr;
 ------- 
|max_arr|
 ------- 
|20     |
 ------- 

--空数组
select array_max(null) as max_arr;
 ------- 
|max_arr|
 ------- 
|null   |
 ------- 

--数组元素都为null
select array_max(array(null, null)) as max_arr;
 ------- 
|max_arr|
 ------- 
|null   |
 ------- 

flatten

对应的类:Flatten

功能描述:将多维数组转换为单个数组,不去重

版本:2.4.0

是否支持全代码生成:支持

用法:

代码语言:javascript复制
--二维数组
select flatten(array(array(1, 2), array(2, 4))) as flatten_arr;
 ------------ 
|flatten_arr |
 ------------ 
|[1, 2, 2, 4]|
 ------------ 

--三维数组
select flatten(array(array(array(1, 2), array(2, 4)))) as flatten_arr;
 ---------------- 
|flatten_arr     |
 ---------------- 
|[[1, 2], [2, 4]]|
 ---------------- 

--有数组为null
select flatten(array(array(1, 2), null)) as flatten_arr;
 ----------- 
|flatten_arr|
 ----------- 
|null       |
 ----------- 

sequence

对应的类:Sequence

功能描述:sequence(start,stop,step)--从开始到停止(包括)生成元素数组,并逐步递

1、返回元素的类型与参数表达式的类型相同,支持的类型有:byte、short、integer、long、date、timestamp

2、start和stop表达式必须解析为同一类型

3、如果开始和停止表达式解析为“date”或“timestamp”类型,则步骤表达式必须解析为“interval”或“year-month interval”或“day-time interval”类型,否则解析为与开始和停止表达式相同的类型。

版本:2.4.0

是否支持全代码生成:支持

用法:

代码语言:javascript复制
--话不多说,看效果
select sequence(1, 5) as seq;
 --------------- 
|seq            |
 --------------- 
|[1, 2, 3, 4, 5]|
 --------------- 

--话不多说,看效果
select sequence(5, 1) as seq;
 --------------- 
|seq            |
 --------------- 
|[5, 4, 3, 2, 1]|
 --------------- 

--话不多说,看效果,自动生成日期列表有救了
select sequence(to_date('2018-01-01'), to_date('2018-03-01'), interval 1 month) as seq;
 ------------------------------------ 
|seq                                 |
 ------------------------------------ 
|[2018-01-01, 2018-02-01, 2018-03-01]|
 ------------------------------------ 

select sequence(to_date('2018-01-01'), to_date('2018-03-01'), interval '0-1' year to month) as seq;
 ------------------------------------ 
|seq                                 |
 ------------------------------------ 
|[2018-01-01, 2018-02-01, 2018-03-01]|
 ------------------------------------ 

array_repeat

对应的类:ArrayRepeat

功能描述:array_repeat(element,count)-返回包含元素计数次数的数组

版本:2.4.0

是否支持全代码生成:支持

用法:

代码语言:javascript复制
--话不多说,看效果
select array_repeat('123', 2) as repeat_arr;
 ---------- 
|repeat_arr|
 ---------- 
|[123, 123]|
 ---------- 

--好用,哈哈
select array_repeat(array(1,2,3), 3) as repeat_arr;
 --------------------------------- 
|repeat_arr                       |
 --------------------------------- 
|[[1, 2, 3], [1, 2, 3], [1, 2, 3]]|
 --------------------------------- 

--元素为null的情况
select array_repeat(null, 3) as repeat_arr;
 ------------------ 
|repeat_arr        |
 ------------------ 
|[null, null, null]|
 ------------------ 

--计数次数为null,好用
select array_repeat(123, null) as repeat_arr;
 ---------- 
|repeat_arr|
 ---------- 
|null      |
 ---------- 

array_remove

对应的类:ArrayRemove

功能描述:array_remove(array, element)-从数组中删除等于元素的所有元素

版本:2.4.0

是否支持全代码生成:支持

用法:

代码语言:javascript复制
--话不多说,看效果
select array_remove(array(1, 2, 3, null, 3), 3) as remove_arr;
 ------------ 
|remove_arr  |
 ------------ 
|[1, 2, null]|
 ------------ 

array_distinct

对应的类:ArrayDistinct

功能描述:array_distinct(array)-数组去重

版本:2.4.0

是否支持全代码生成:支持

用法:

代码语言:javascript复制
--话不多说,看效果
select array_distinct(array(1, 2, 3, null, 3)) as distinct_arr;
 --------------- 
|distinct_arr   |
 --------------- 
|[1, 2, 3, null]|
 --------------- 

collection_funcs

array_size

对应的类:ArraySize(实际调用的是Size类,参数legacySizeOfNull传入false,也就是说当数组为null时,array_size默认返回null)

功能描述:返回数组的大小

1、对于null输入,函数返回null

2、可对array和map结果求size

版本:3.3.0

是否支持全代码生成:支持

用法:

代码语言:javascript复制
--正常情况的案例
select array_size(array('b', 'd', 'c', 'a')) as arr_size;
 -------- 
|arr_size|
 -------- 
|4       |
 -------- 

--对于null输入,函数返回null
select array_size(null) as arr_size;
 -------- 
|arr_size|
 -------- 
|null    |
 -------- 

size

对应的类:Size(与array_size不同的是,legacySizeOfNull参数由spark.sql.legacy.sizeOfNull和spark.sql.ansi.enabled共同决定,默认返回值为true,即当数组为null时,size返回-1)

功能描述:返回数组的大小

1、对于null输入,函数返回-1

2、可对array和map结果求size

版本:1.5.0

是否支持全代码生成:支持

用法:

代码语言:javascript复制
--正常情况的案例
select size(array('b', 'd', 'c', 'a')) as arr_size;
 -------- 
|arr_size|
 -------- 
|4       |
 -------- 

--对于null输入,函数返回-1
select size(null) as arr_size;
 -------- 
|arr_size|
 -------- 
|-1      |
 -------- 

cardinality

对应的类:Size(与size不同的是,legacySizeOfNull参数默认传入true,即当数组为null时,size返回-1;而size的legacySizeOfNull参数是由spark.sql.legacy.sizeOfNull和spark.sql.ansi.enabled共同决定,默认返回值为true,但如果我们改配置参数,会影响legacySizeOfNull的值)

功能描述:返回数组的大小

1、对于null输入,函数返回-1

2、可对array和map结果求size

版本:1.5.0

是否支持全代码生成:支持

用法:

代码语言:javascript复制
--正常情况的案例
select cardinality(array('b', 'd', 'c', 'a')) as arr_size;
 -------- 
|arr_size|
 -------- 
|4       |
 -------- 

--对于null输入,函数返回-1
select cardinality(null) as arr_size;
 -------- 
|arr_size|
 -------- 
|-1      |
 -------- 

reverse

对应的类:Reverse

功能描述:返回反向字符串或元素顺序相反的数组

版本:1.5.0,从2.4.0版本开始支持数组reverse

是否支持全代码生成:支持

用法:

代码语言:javascript复制
--正常案例
select reverse(array(1, 20, null, 3)) as reverse_arr;
 ---------------- 
|reverse_arr     |
 ---------------- 
|[3, null, 20, 1]|
 ---------------- 

--空数组
select reverse(null) as reverse_arr;
 ----------- 
|reverse_arr|
 ----------- 
|null       |
 ----------- 

concat

对应的类:Concat

功能描述: concat(col1,col2,…,colN)-将字符串或者数组拼接,不去重

版本:1.5.0,从2.4.0版本开始支持数组concat

是否支持全代码生成:支持

用法:

代码语言:javascript复制
select concat(array(1, 2, 3), array(3, 4, 5), array(6)) as concat_arr;
 --------------------- 
|concat_arr           |
 --------------------- 
|[1, 2, 3, 3, 4, 5, 6]|
 --------------------- 

--空数组
select concat(null) as concat_arr;
 ---------- 
|concat_arr|
 ---------- 
|null      |
 ---------- 

--有一个数组为null,会报错
select concat(array(1, 2, 3), array(3, 4, 5), array(6),null) as concat_arr;

cannot resolve 'concat(array(1, 2, 3), array(3, 4, 5), array(6), CAST(NULL AS STRING))' due to data type mismatch: input to function concat should all be the same type, but it's [array<int>, array<int>, array<int>, string]; line 1 pos 7;
'Project [concat(array(1, 2, 3), array(3, 4, 5), array(6), cast(null as string)) AS concat_arr#218]
 - OneRowRelation

map_funcs

element_at

对应的类:ElementAt

功能描述:返回给定(基于1的)索引处的数组元素。

1、如果索引为0,将抛出一个错误

2、如果索引<0,则从最后一个到第一个访问元素

3、如果索引超过数组的长度 且spark.sql.ansi.enabled 参数设置为false ,则函数返回NULL

4、如果索引超过数组的长度 且spark.sql.ansi.enabled 参数设置为true ,则抛出ArrayIndexOutOfBoundsException

版本:2.4.0

是否支持全代码生成:支持

用法:

代码语言:javascript复制
--输入索引为正
select element_at(array(1, 5, 2, 3), 2) as ele;
 --- 
|ele|
 --- 
|5  |
 --- 

--输入索引为负
select element_at(array(1, 5, 2, 3), -2) as ele;
 --- 
|ele|
 --- 
|2  |
 --- 

--输入索引超过数组的长度
select element_at(array(1, 5, 2, 3), 5) as ele;
 ---- 
|ele |
 ---- 
|null|
 ---- 

lambda_funcs

array_sort

对应的类:ArraySort

功能描述:使用比较器函数对数组中的元素排序

1、输入数组的元素必须是可排序的

2、对于双/浮点类型,NaN大于任何非NaN元素

3、默认比较器,是按升序排序,Null元素将放置在返回的数组的末尾

4、自3.0.0以来,该函数还基于给定的比较器函数对数组进行排序和返回。比较器将采用两个参数,表示数组的两个元素。当第一个元素小于、等于或大于第二个元素时,它返回一个负整数、0或正整数。如果比较器函数返回null,该函数将失败并引发错误

从源码中可以看到,有两个构造函数,用来分别支持输入比较函数和不输入比较函数的情况,而SQLConf.LEGACY_ALLOW_NULL_COMPARISON_RESULT_IN_ARRAY_SORT 参数(默认为false),当设置为false时,如果比较器函数返回null,“array_sort”函数将抛出异常。如果设置为true,将把null处理为零

版本:2.4.0

是否支持全代码生成:不支持

用法:

代码语言:javascript复制
--用默认比较器
select array_sort(array('b', 'd', null, 'c', 'a')) as sort_arr;
 ------------------ 
|sort_arr          |
 ------------------ 
|[a, b, c, d, null]|
 ------------------ 

--自定义比较器,按升序排
select array_sort(array(5, 6, 1), (left, right) -> case when left < right then -1 when left > right then 1 else 0 end) as sort_arr;
 --------- 
|sort_arr |
 --------- 
|[1, 5, 6]|
 --------- 

--自定义比较器,按降序排
select array_sort(array('bc', null,null, 'ab', 'dc'), (left, right) -> case when left is null and right is null then 0 when left is null then -1 when right is null then 1 when left < right then 1 when left > right then -1 else 0 end) as sort_arr;
 ------------------------ 
|sort_arr                |
 ------------------------ 
|[null, null, dc, bc, ab]|
 ------------------------ 

transform

对应的类:ArrayTransform

功能描述:transform(expr, func)--使用函数变换数组中的元素

版本:2.4.0

是否支持全代码生成:不支持

用法:

代码语言:javascript复制
select transform(array(1, 2, 3), x -> x   1) as transform_arr;
 ------------- 
|transform_arr|
 ------------- 
|[2, 3, 4]    |
 ------------- 

--相邻相加
select transform(array(1, 2, 3), (x, i) -> x   i) as transform_arr;
 ------------- 
|transform_arr|
 ------------- 
|[1, 3, 5]    |
 ------------- 

filter

对应的类:ArrayFilter

功能描述:filter(expr, func)--使用给定谓词过滤输入数组

版本:2.4.0

是否支持全代码生成:不支持

用法:

代码语言:javascript复制
--话不多说,看效果1
select filter(array(1, 2, 3), x -> x % 2 == 1) as filter_arr;
 ---------- 
|filter_arr|
 ---------- 
|[1, 3]    |
 ---------- 

--话不多说,看效果2
select filter(array(0, 2, 3), (x, i) -> x > i) as filter_arr;
 ---------- 
|filter_arr|
 ---------- 
|[2, 3]    |
 ---------- 

--话不多说,看效果3
select filter(array(0, null, 2, 3, null), x -> x IS NOT NULL) as filter_arr;
 ---------- 
|filter_arr|
 ---------- 
|[0, 2, 3] |
 ---------- 

exists

对应的类:ArrayExists

功能描述:exists(expr, pred)--测试谓词是否适用于数组中的一个或多个元素

版本:2.4.0

是否支持全代码生成:不支持

用法:

代码语言:javascript复制
--话不多说,看效果1
select exists(array(1, 2, 3), x -> x % 2 == 0) as exists_flag;
 ----------- 
|exists_flag|
 ----------- 
|true       |
 ----------- 

--话不多说,看效果2
select exists(array(1, 2, 3), x -> x % 2 == 10) as exists_flag;
 ----------- 
|exists_flag|
 ----------- 
|false      |
 ----------- 

--话不多说,看效果3
select exists(array(1, null, 3), x -> x % 2 == 0) as exists_flag;
 ----------- 
|exists_flag|
 ----------- 
|null       |
 ----------- 

--话不多说,看效果4
select exists(array(0, null, 2, 3, null), x -> x IS NULL) as exists_flag;
 ----------- 
|exists_flag|
 ----------- 
|true       |
 ----------- 

--话不多说,看效果5
select exists(rray(1, 2, 3), x -> x IS NULL) as exists_flag;
 ----------- 
|exists_flag|
 ----------- 
|false      |
 ----------- 

forall

对应的类:ArrayForAll

功能描述:forall(expr, pred)--测试谓词是否适用于数组中的所有元素

版本:3.0.0

是否支持全代码生成:不支持

用法(案例3和案列4需要仔细品):

代码语言:javascript复制
--话不多说,看效果1
select forall(array(1, 2, 3), x -> x % 2 == 0) as forall_flag;
 ----------- 
|forall_flag|
 ----------- 
|false      |
 ----------- 

--话不多说,看效果2
select forall(array(2, 4, 8), x -> x % 2 == 0) as forall_flag;
 ----------- 
|forall_flag|
 ----------- 
|true       |
 ----------- 


--话不多说,看效果3
select forall(array(1, null, 3), x -> x % 2 == 0) as forall_flag;
 ----------- 
|forall_flag|
 ----------- 
|false      |
 ----------- 

--话不多说,看效果4
select forall(array(2, null, 8), x -> x % 2 == 0) as forall_flag;
 ----------- 
|forall_flag|
 ----------- 
|null       |
 ----------- 

aggregate

对应的类:ArrayAggregate

功能描述:aggregate(expr, start, merge, finish)--将二进制运算符应用于初始状态和数组中的所有元素,并将其简化为单个状态。通过应用finish函数将最终状态转换为最终结果(好难理解,其实就是按照一定的初始值,一定的规则,把数组的元素聚合成一个值,看案例就懂了,非常灵活)

版本:2.4.0

是否支持全代码生成:不支持

用法:

代码语言:javascript复制
--初始值为0,累加
select aggregate(array(1, 2, 3), 0, (acc, x) -> acc   x) as agg;
 --- 
|agg|
 --- 
|6  |
 --- 

--初始值为0,*10,累加
select aggregate(array(1, 2, 3), 0, (acc, x) -> acc   x, acc -> acc * 10) as agg;
 --- 
|agg|
 --- 
|60 |
 --- 

zip_with

对应的类:ZipWith

功能描述:zip_with(left, right, func)--使用函数将两个给定数组按元素合并为单个数组;如果一个数组较短,则在应用函数之前,在末尾追加null以匹配较长数组的长度

版本:2.4.0

是否支持全代码生成:不支持

用法:

代码语言:javascript复制
--话不多说,看效果1
--两个数组长度一样,匹配
select zip_with(array(1, 2, 3), array('a', 'b', 'c'), (x, y) -> (y, x)) as zips;
 ------------------------ 
|zips                    |
 ------------------------ 
|[{a, 1}, {b, 2}, {c, 3}]|
 ------------------------ 

--两个数组长度不一样,追加null
select zip_with(array(1, 2, 3), array('a', 'b'), (x, y) -> (y, x))  as zips;
 ------------------------  --------------------------- 
|zips                       |
 --------------------------- 
|[{a, 1}, {b, 2}, {null, 3}]|
 --------------------------- 

--话不多说,看效果2
select zip_with(array(1, 2), array(3, 4), (x, y) -> x   y) as zips;
 ------ 
|zips  |
 ------ 
|[4, 6]|
 ------ 

--话不多说,看效果3
select zip_with(array('a', 'b', 'c'), array('d', 'e', 'f'), (x, y) -> concat(x, y)) as zips;
 ------------ 
|zips        |
 ------------ 
|[ad, be, cf]|
 ------------ 

以上!

0 人点赞