scala - 从合并两个Map说开去 - foldLeft 和 foldRight 还有模式匹配

开发中遇到需求:合并两个Map集合对象(将两个对应KEY的值累加)

先说解决方案:

( map1 /: map2 ) { case (map, (k,v)) => map + ( k -> (v + map.getOrElse(k, 0)) ) }

这特么什么鬼  (╯‵□′)╯""┻━┻☆))>○<) 。。。。。。莫急,且听我慢慢道来。。。。。。。。。



首先:

Scala中现有的合并集合操作不能满足这个需求 。

注意合并后的结果a的G02的值其实是被覆盖掉了。。

然后:

说说那个表达式中(a /: b)( ... ) 这部分是什么鬼。这个其实是scala简化的foldLeft函数。

先看foldLeft

List(1,2,3).foldLeft(0)((sum,i)=>sum+i)  // 红色部分是初始值,蓝色部分是操作函数

List(1,2,3).foldLeft(0)((sum,i)=>sum+i)
可以写成
(List(1,2,3) foldLeft 0)((sum,i)=>sum+i)
语法糖
(0 /: List(1,2,3))(_+_)  

操作符设计者的脑洞也是够了 - - 开发者绝对是表情帝

如果接受了这个设定。。。foldRight也可以脑补出来。。 一定是  ((1 to 5) :\ 100)((i,sum)=> sum-i) .......

另外。一个例子说明  foldLeft 和 foldRight:

 最后:

来说说操作函数中的case  ,这个鬼叫模式匹配 (哦对,模式匹配的时候是要有个大括号包起来的 所以最终结果的操作函数使用大括号包着。)

Map的折叠函数是依次传入Map的键值对。所以操作函数希望传入的操作数可以是(K,V)形式。。于是用case表达式:(map, (k,v))

具体模式匹配是什么。。简单说就是scala会尝试将传入的值匹配到case后面表达式的样子(当然这里一定会匹配上,所以没有写case的多余分支)具体什么是“模式匹配”,目前理解尚浅此处暂不深入妄加揣测。

壹 Try 胜千言 :



参考

1) http://stackoverflow.com/questions/7076128/best-way-to-merge-two-maps-and-sum-the-values-of-same-key

2) http://blog.csdn.net/wsscy2004/article/details/37698013

3) http://my.oschina.net/sulliy/blog/58266

时间: 2024-08-25 16:23:53

scala - 从合并两个Map说开去 - foldLeft 和 foldRight 还有模式匹配的相关文章

从合并两个Map说开去 - foldLeft 和 foldRight 还有模式匹配

开发中遇到需求:合并两个Map集合对象(将两个对应Key的值累加) 先说解决方案: ( map1 /: map2 ) { case (map, (k,v)) => map + ( k -> (v + map.getOrElse(k, 0)) ) } 首先: Scala中现有的合并集合操作不能满足这个需求 . 注意合并后的结果a的G02的值其实是被覆盖掉了.. 然后: 说说那个表达式中(a /: b)( ... ) 这部分是什么鬼.这个其实是scala简化的foldLeft函数. 先看foldL

Clojure:将两个list合并成一个map

假设我们有两个list,分别是: (def a [“one” “two” “three”]) (def b [1 2 3]) 我们要把它们合为一个键值对应的map,做法很简单: 1. 先将a和b合为一个一一对应的list: (map vector a b) => (["one" 1] ["two" 2] ["three" 3]) 2. 然后再将list转化成为map: (into {} (map vector a b)) => {&q

两个map合并

两个map合并所用函数为:putAll package myProject; import java.util.HashMap; import java.util.Map; public class TestMapMerge { public static void main(String[] args) { Map<String,Object> map1=new HashMap<String,Object>(); Map<String,Object> map2=new

如何用 Git 合并两个库,并保留提交历史

转载自 https://segmentfault.com/a/1190000000678808 背景 一个中型规模项目,开始规划时就打算采用 C/S 架构,后端是单纯的 API 服务,前端在 Web 上搞一个 SPA,之后再搞其他端也就顺理成章了.只可以第一次弄没经验,有些细节最初没有考虑到. 创建项目的时候前后端真是完全分离的,分成了两个目录,创建了两个 repos.一开始只有一个人干的时候倒也没什么,开两个窗口切来切去也就罢了,后来一是部署起来麻烦,二来主要是其他开发者加入后,代码的版本管理

编写Spark的WordCount程序并提交到集群运行[含scala和java两个版本]

编写Spark的WordCount程序并提交到集群运行[含scala和java两个版本] 1. 开发环境 Jdk 1.7.0_72 Maven 3.2.1 Scala 2.10.6 Spark 1.6.2 Hadoop 2.6.4 IntelliJ IDEA 2016.1.1 2. 创建项目1) 新建Maven项目 2) 在pom文件中导入依赖pom.xml文件内容如下: <?xml version="1.0" encoding="UTF-8"?> &l

合并两个有序单链表

给出两个有序的单链表,将这两个单链表进行合并,合并出来的链表仍然是有序的. 比如给出链表1:1->3->6->7;链表2:2->4->5->8->9 合并后的链表为:1->2->3->4->5->6->7->8->9 代码展示如下(只给出实现部分) 结构体定义: typedef struct LinkNode { DataType data; struct LinkNode *next; }LinkNode,*pLi

链表(14)----合并两个有序链表

1.链表定义 typedef struct ListElement_t_ { void *data; struct ListElement_t_ *next; } ListElement_t; typedef struct List_t_{ int size; int capacity; ListElement_t *head; ListElement_t *tail; } List_t; 2.合并两个有序链表 ListElement_t * MergeList( ListElement_t *

数据结构中线性表的基本操作-合并两个线性表-依照元素升序排列

#include<iostream> #include<stdlib.h> #define LIST_INIT_SIZE 10/*线性表初始长度*/ #define LIST_CREATENT 2/*每次的增量*/ typedef int ElemType; using namespace std; typedef struct SqList/*线性表的数据结构定义*/ { ElemType *elem;/*线性表基址*/ int length;/*当前线性表所含的元素个数*/ i

java合并两段音频成一段 同时播放类似伴奏

/** * * @param partsPaths 要合成的音频路径数组 * @param unitedFilePath 输入合并结果数组 */ public void uniteWavFile(String[] partsPaths, String unitedFilePath) { byte byte1[] = getByte(partsPaths[0]); byte byte2[] = getByte(partsPaths[1]); byte[] out = new byte[byte1.