7、Map函数



7、Map函数

0、概述

分类函数功能
map处理MAP使用指定的Key-Value对建立MAP。
map处理MAP_CONCAT返回多个MAP的并集。
map处理MAP_ENTRIES将MAP中的Key、Value键值映射转换为STRUCT结构数组。
map处理MAP_FILTER将MAP中的元素进行过滤。
map处理MAP_FROM_ARRAYS通过给定的ARRAY数组构造MAP。
map处理MAP_FROM_ENTRIES通过给定的结构体数组构造MAP。
map处理MAP_KEYS将参数MAP中的所有Key作为数组返回。
map处理MAP_VALUES将参数MAP中的所有Value作为数组返回。
map处理MAP_ZIP_WITH对输入的两个MAP进行合并得到一个新MAP。
map处理MULTIMAP_FROM_ENTRIES结构体数组中返回一个MAP。
转换TRANSFORM_KEYS对MAP进行变换,保持Value不变,根据指定函数计算新的Key。
转换TRANSFORM_VALUES对MAP进行变换,保持Key不变,根据指定函数计算新的Value。
其它SIZE返回指定MAP中的K/V对数。
其它INDEX返回MAP类型参数中满足指定条件的Value。
其它EXPLODE将一行数据转为多行的UDTF。

1、Map处理

  • MAP:使用指定的Key-Value对建立MAP。
map(K, V) map(K <key1>, V <value1>, K <key2>, V <value2>[, ...])
-- {"b":2,"a":1}
SELECT map('a',1,'b',2);

-- 将c2、c4,c3、c5组成MAP。
select map(c2,c4,c3,c5) from t_table;
  • MAP_CONCAT:返回多个MAP的并集。
map<K, V> map_concat([string <mapDupKeyPolicy>,] map<K, V> <a>, map<K, V> <b>[,...])
  • 入参
    • mapDupKeyPolicy:可选。STRING类型。指定出现重复Key时的处理方式。取值范围如下:
      • exception:如果出现重复的Key,返回报错。
      • last_win:如果出现重复的Key,后边的值将覆盖前边的值。
-- {"d":4,"a":1,"b":2}
SELECT map_concat(map('a',1,'b',2),map('d',4));
-- {"b":2,"a":5}
SELECT map_concat('last_win',map('a',1) ,map('a',5,'b',2));
  • MAP_ENTRIES:将MAP中的Key、Value键值映射转换为STRUCT结构数组。
array<struct<K, V>> map_entries(map<K, V> <a>): 
-- [{key:a, value:1}, {key:b, value:2}]
SELECT map_entries(map('a',1,'b',2));
  • MAP_FILTER:将MAP中的元素进行过滤。
map<K, V> map_filter(map<K, V> <input>, function <K, V, boolean> <predicate>)
  • 入参
    • input:必填。MAP类型。
      predicate:必填。用于对输入MAP对象中的元素进行过滤的函数(内建函数或自定义函数)或表达式。
-- {"3":4,"5":6}
SELECT map_filter(map(1,2,3,4,5,6) ,(x,y)-> (x+y)>5);
  • MAP_FROM_ARRAYS:通过给定的ARRAY数组构造MAP。
map<K, V> map_from_arrays([string <mapDupKeyPolicy>,] array<K> <a>, array<V> <b>)
  • 入参
    • mapDupKeyPolicy:可选。STRING类型。指定出现重复Key时的处理方式。取值范围如下:
      • exception:如果出现重复的Key,返回报错。
      • last_win:如果出现重复的Key,后边的值将覆盖前边的值。
-- {"a":1,"b":2,"c":3}
SELECT map_from_arrays(array('a','b','c') ,array(1,2,3));
-- {"b":3,"a":1}
SELECT map_from_arrays('last_win' ,array('a','b','b') ,array(1,2,3));
  • MAP_FROM_ENTRIES:通过给定的结构体数组构造MAP。
map<K, V> map_from_entries([string <mapDupKeyPolicy>,] array <struct<K, V> , struct<K, V>[,...]>)
  • 入参
    • mapDupKeyPolicy:可选。STRING类型。指定出现重复Key时的处理方式。取值范围如下:
      • exception:如果出现重复的Key,返回报错。
      • last_win:如果出现重复的Key,后边的值将覆盖前边的值。
-- [{col1:a, col2:1}, {col1:b, col2:2}]
SELECT array(struct('a',1),struct('b',2));
-- {"b":2,"a":1}
SELECT map_from_entries(array(struct('a',1),struct('b',2)));
  • MAP_KEYS:将参数MAP中的所有Key作为数组返回。
array<K> map_keys(map<K, V> <a>)
select c1, map_keys(t_map) from t_table_map;
  • MAP_VALUES:将参数MAP中的所有Value作为数组返回。
array<V> map_values(map<K, V> <a>)
select c1,map_values(t_map) from t_table_map;
  • MAP_ZIP_WITH:对输入的两个MAP进行合并得到一个新MAP。
    • 先2个map取并集,然后再传入后面Lambda函数进行计算
    • k为键、v1、v2为值。
<K, V1, V2, V3> map<K, V3> map_zip_with(map<K, V1> <input1>, map<K, V2> <input2>, function<K, V1, V2, V3> <func>)
-- {"b":["b","2","4"],"a":["a","1","3"]}
SELECT map_zip_with(map('a',1,'b',2), map('a',3,'b',4)
            , (k, v1, v2) -> array(k, v1, v2));

-- {"a":["a","1","3"],"b":["b","2","2"],"c":["c",null,"4"]}
select map_zip_with(map('a',1,'b',2), map('a',3,'b',2,'c',4)
            , (k, v1, v2) -> array(k, v1, v2));
  • MULTIMAP_FROM_ENTRIES:结构体数组中返回一个MAP。
    multimap_from_entries(array<struct<K, V>>)
-- {"2":["b"],"1":["a","c"]}
SELECT multimap_from_entries(array(
                                struct(1, 'a'), 
                                struct(2, 'b'), 
                                struct(1, 'c')));

2、转换

  • TRANSFORM_KEYS:对MAP进行变换,保持Value不变,根据指定函数计算新的Key。
map<K2, V> transform_keys([string <mapDupKeyPolicy>,] map<K1, V> <input>, function<K1, V, K2> <func>)
  • 入参
    • mapDupKeyPolicy:可选。STRING类型。指定出现重复Key时的处理方式。取值范围如下:
      • exception:如果出现重复的Key,返回报错。
      • last_win:如果出现重复的Key,后边的值将覆盖前边的值。
-- {"a1":1,"b2":2}
SELECT transform_keys(map('a',1,'b',2), (k,v)->concat(k,v));
-- {"b2":2,"a3":3}
SELECT transform_keys('last_win' ,map('a',1,'b',2,'a',3) ,(k,v)->concat(k,v));

  • TRANSFORM_VALUES:对MAP进行变换,保持Key不变,根据指定函数计算新的Value。
map<K, V2> transform_values(map<K, V1> <input>, function<K, V1, V2> <func>)
-- {"b":"b2","a":"a1"}
SELECT transform_values(map('a',1,'b',2),(k,v)->concat(k,v));

3、其它

  • SIZE:返回指定ARRAY中的元素数目。
int size(array<T> <a>)
int size(map<K, V> <b> )
  • 入参
    • a:必填。ARRAY数组。
    • b:必填。MAP对象。
-- 3
SELECT size(array(1,2,3));
-- 2
SELECT size(map('a',1,'b',2));
  • INDEX:返回ARRAY数组指定位置的元素值。
INDEX (<var1>[<var2>])
  • 入参
    • var1:必填。array<T>类型或map<K, V>类型。
    • var2:必填。
      • array<T>类型,为BIGINT类型且大于等于0。
      • map<K, V>类型,与K的类型保持一致。
-- 3
SELECT array(1,2,3,4)[2];
-- 2
SELECT map('a',1,'b',2,'c',3)['b'];
  • EXPLODE:将一行数据转为多行的UDTF。
explode (<var>)
  • 入参
    • 如果参数是array<T>类型,则将列中存储的ARRAY转为多行。
    • 如果参数是map<K, V>类型,则将列中存储的MAP的每个Key-Value对转换为包含两列的行,其中一列存储Key,另一列存储Value。
    • 如果表中存在NULL数据,不会单独返回。
-- 源数据
+------------+-------+
| c1         | t_map |
+------------+-------+
| 1000       | {k11:86, k21:15} |
| 1001       | {k12:97, k22:2} |
| 1002       | {k13:99, k23:1} |
+------------+-------+

select explode(t_map) from t_table_map;
--返回结果如下。
+-----+------------+
| key | value      |
+-----+------------+
| k11 | 86         |
| k21 | 15         |
| k12 | 97         |
| k22 | 2          |
| k13 | 99         |
| k23 | 1          |
+-----+------------+
<think>我们被要求回答关于Scala中map函数的使用方法和相关知识。根据提供的引用,我们可以总结如下: 引用[1]指出:.map是一个高阶函数,用于对集合中的每个元素应用一个函数,并返回一个新的集合。 引用[2]展示了如何将方法作为参数传递给map函数(因为Scala中方法可以自动转换为函数)。 引用[3]详细说明了map函数的作用:遍历集合、转换元素、不改变原集合、简化代码,并给出了一个示例。 引用[4]给出了一个使用map将数组每个元素乘以2的示例。 因此,我们的回答应涵盖以下内容: 1. map函数的基本概念:高阶函数,用于转换集合中的每个元素,返回新集合。 2. map函数的特点:不改变原集合(函数式编程的不可变性)。 3. 使用方法:可以直接传递函数字面量(匿名函数)或已定义的方法(方法会自动转换为函数)。 4. 示例代码。 同时,根据系统指令: - 行内数学表达式使用$...$(但本问题可能不涉及数学表达式,所以可以忽略) - 独立公式使用$$...$$(同样,可能不需要) - 使用中文回答 - 生成相关问题 另外,注意在回答中引用的段落末尾添加引用标识。 回答结构建议: 1. 介绍map函数。 2. 解释map函数的工作原理和特点。 3. 展示使用示例(代码)。 4. 讨论为什么可以将方法传递给map(根据引用[2])。 5. 注意事项(如果有)。 6. 生成相关问题。 注意:引用标识要自然地添加在引用的内容末尾。由于我们参考了多个引用,需要标注清楚。 示例回答: ### Scala中的map函数 在Scala中,`map`是一个高阶函数,用于对集合(如List、Array等)中的每个元素应用一个给定的函数,并返回一个新的集合,新集合的元素是原集合元素经过该函数转换后的结果。`map`函数体现了函数式编程的核心思想之一:不可变性(即原始集合不会被修改)[^1][^3]。 #### map函数的特点 1. **遍历与转换**:`map`会遍历集合中的每个元素,并对每个元素应用指定的转换函数。 2. **返回新集合**:转换的结果会存入一个新的集合中,而原始集合保持不变[^3]。 3. **代码简洁**:使用`map`可以避免显式的循环,使代码更简洁和易读[^3]。 #### 使用方法 `map`函数的使用形式为: ```scala val newCollection = collection.map(f) ``` 其中,`collection`是原始集合,`f`是一个函数,它接收一个元素(类型为原集合元素的类型)并返回一个新值(类型可以不同)。 参数`f`可以是: - 一个函数字面量(匿名函数) - 一个已经定义的方法(Scala会自动将方法转换为函数)[^2] ##### 示例1:使用匿名函数 ```scala val numbers = List(1, 2, 3, 4, 5) val doubled = numbers.map(x => x * 2) // doubled: List(2,4,6,8,10) ``` ##### 示例2:使用方法 ```scala def multiplyByThree(x: Int): Int = x * 3 val tripled = numbers.map(multiplyByThree) // tripled: List(3,6,9,12,15) ``` 在示例2中,我们定义了一个方法`multiplyByThree`,然后将其作为参数传递给`map`函数。这是因为Scala编译器会自动将方法转换为一个函数(这个过程称为ETA展开)[^2]。 #### 注意事项 - `map`函数可以用于任何集合类型(如List、Array、Set、Map等),但对于Map集合,`map`操作的是键值对(元组)。 - 转换函数的返回值类型可以不同于输入类型,因此我们可以将集合中的元素转换成任意类型。 例如,将整数列表转换为字符串列表: ```scala val strings = numbers.map(x => s"Number: $x") ``` #### 总结 `map`是Scala中非常强大且常用的函数,它允许我们以一种声明式的方式对集合进行转换操作,避免了命令式编程中的循环和临时变量。掌握`map`对于编写函数式风格的Scala代码至关重要。 §§相关问题§§ 1. Scala中的`map`函数与`flatMap`函数有何区别? 2. 除了`map`,Scala中还有哪些常用的高阶函数? 3. 在Scala中,如何对Map集合使用`map`函数? 4. 为什么说`map`函数体现了函数式编程的不可变性? </think>### Scala中的`map`函数详解 `map`是Scala函数式编程的核心高阶函数,用于对集合元素进行转换操作。以下结合引用内容详细说明: #### 一、核心概念 1. **转换本质** `map`遍历集合中的每个元素,对其应用指定函数,生成包含转换结果的新集合,原始集合保持不变[^1][^3]。 数学表示:$f: A \rightarrow B$,输入集合$[a_1, a_2, ..., a_n]$,输出$[f(a_1), f(a_2), ..., f(a_n)]$ 2. **函数式特性** - 不修改原集合(满足不可变性原则)[^3] - 返回新集合,类型可与原集合不同 - 支持链式调用(如`list.map(f).map(g)`) #### 二、使用方法 ##### 1. 基础语法 ```scala val newCollection = originalCollection.map(转换函数) ``` ##### 2. 参数类型 可接受**函数**或**方法**作为参数(Scala自动将方法转为函数)[^2]: ```scala // 方式1:匿名函数(直接定义) List(1,2,3).map(x => x * 2) // 返回 List(2,4,6) // 方式2:预定义方法 def triple(n: Int) = n * 3 List(1,2,3).map(triple) // 返回 List(3,6,9)[^2] ``` ##### 3. 集合类型支持 适用于所有标准集合: ```scala // List示例 List("a","b").map(_.toUpperCase) // List("A","B") // Array示例(引用[4]) Array(1,2,3,4).map(a => 2*a) // Array(2,4,6,8)[^4] // Map特殊处理(注意操作的是键值对) Map(1->"A", 2->"B").map { case (k,v) => (k+10, v) } // Map(11->"A", 12->"B") ``` #### 三、关键特性 1. **延迟计算** 在`View`或`LazyList`中使用时,转换按需执行,提升性能。 2. **类型推断** Scala能自动推断返回类型: ```scala val nums: List[String] = List(1,2,3).map(_.toString) // 自动推断为List[String] ``` 3. **并行处理** 通过`.par`启用并行`map`: ```scala (1 to 100000).par.map(_ * 2) // 多线程并行计算 ``` #### 四、注意事项 1. 转换函数应**无副作用**,避免修改外部状态 2. 对`Option`集合操作时,`map`仅处理`Some`值: ```scala Some(5).map(_ * 2) // Some(10) None.map(_ * 2) // None(无操作) ``` 3. 与`flatMap`区别:`map`返回嵌套集合时需用`flatMap`展开
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ha_lydms

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值