00:00
我们已经了解了scla集合当中的高级计算函数,那接下来呢,我们就来举一个具体的事例,让大家对高级计算函数有更深刻的理解,那我们首先重新来考虑一下。之前我们介绍过的map里边的合并操作,之前我们在讲到map合并的时候呢,是直接调用了加加或者加加等于方法,这样就把两个map里边的内容合并在一起了,但是我们会发现这里边是有一些瑕疵的,就比如说我们MAP2加加MAP1,如果MAP1里边的元素是MAP2里边没有的话,那是直接添加进去,这个是我们能考虑到的,但是如果说MAP1和MAP2里边有相同的K的话,那这个操作其实是把MAP1里边的值覆盖掉MAP2里面的值了,最后得到的结果是以MAP1为准。所以如果说我们MAP1加加MAP2和MAP2加加MAP1,得到的结果其实是有可能不同的,我们总是用后边的这个map里边的值覆盖之前map里面的值啊,这种行为在有一些场景下是呃合理的,但是有更多的场景我们会觉得这种不合理,我们要做的是map的合并,而不是覆盖。
01:23
诶,所以接下来我们就另外给大家讲解一种真正意义上的合并两个map的操作,那这就要用到我们刚刚学习过的高级计算函数里的规约,我们首先还是新建一个测试的GALA object,现在是TEST16。我们现在要测试的是方法写出来。那首先我们还是要先定义两个map,我们直接用半生对象把当前的map定义出来,呃,我们可以给一个字符串类型的key,然后给一个int类型的值,然后给一个。
02:13
对应的可以给一个C数据的话,我们可以随便几个就可以了,有一个MAP1,另外再来一个MAP2。同样我们拥有ABC3个K,那里面的值呢?不太相同,一是六,一是二。C是哦,哎,那对应的我们还可以再多增加一个对应的值,三有了对应,呃,当前map的定义之后,接下来我们就考虑到按照之前我们想啊,直接用加加操作的话,那这个非常明显得到的结果会以MAP2里边的为准,因为MAP1里边所有的k map2里边都有,所以我们得到最后合并的结果其实就是MAP2的值啊,这个并不是我们想要的,我们本来想的像这种。
03:19
这种类型的合并的话,那应该很有可能,它就是我们要统计每一个字母或者每一个单词出现的频率,我们做大数据处理的时候,往往是一个分布式计算,那一部分数据我们算出来A里出现的个数是一,那么另外一部分呢,A出现的是六,那么当前如果我们要合并,那应该是把一和六相加才是整体来看A。所有出现的频次,哎,那所以当前我们应该是判断,如果是相同K的话,应该做一个把它们对应的value相加的操作,而不是直接覆盖。那怎么样能够实现这样的一个功能呢?那我们自然就想到了,我们可以以某一个map作为。
04:09
一个起始的基准,然后再把另外一个map里边的每一个k value做一个便利,每一个k value去判断一下当前的K在不在我们基准的那个map里,如果不在的话,直接添加,如果在的话,那就需要把当前的value都取出来,叠加之后再做一个更新操作。所以整体来看的话,那我们其实就是把作为基准的那个map,这不就可以作为状态的初始值,然后遍历另外一个map里边的k value,对,去更新这个状态吗?哎,所以这样看的话,我们其实就可以用到集合里边的一个高级计算函数,就是reduce或者fo的这样的一个规约操作了,当前我们既然是涉及到了有初始值,那自然就应该是fold了啊,那这里边还涉及到一个我们想要用其中的某一个map作为一个状态不停的改变,那如果我们直接用不可变的map的话,显然是做不到这个效果的。
05:16
比方说我们想要用MAP2作为一个基准的,就是以它为标准进行去更改,那把它作为一个状态不停的更新,那么我们就把它定义成可变的map map multipleable引入,这样的话,MAP1不需要是可变的啊,我们只要遍历MAP1里边的每一个元素,去判断K是否在MAP2中,然后更新MAP2的值就可以了,最后把MAP2返回。啊,那这是我们当前能够想到的这种操作,那具体的实现呢,从这里边第一个那么三作为我们返回的,他们合并之后返回的结果。首先我们是以MAP2作为初始值,那自然就是要遍利MAP1里面的元素了,所以是MAP1去调用一个规约方法要用for,这里大家还需要注意,就是for里边我们传的这个操作,Top里边对应的这两个,一个参数是当前的聚合状态,另外一个是我们要遍历的元素的。
06:26
当下一个新的元素,那么他们定义的这个类型呢,必须是一样的,必须是相同的。我们现在其实不相同,因为我们的状态是一个map,而当前我们做便利的元素呢,是一个k value,对,是一个元组,二元组。那怎么解决这个问题呢?我们就回忆起来之前你曾调用的Ford left,它是允许它俩不同的。所当前,哎,这也是提到了fold和fold left的一个不同,我们这里不能用fold,只能用forld left啊,那接下来我们就是要先给一个初始值F图二,然后接下来自然就是一个操作了,要解一个拉姆达表达式,这里的拉姆达表达式同样是两个参数,传入两个参数,一个是表示我们当前的聚合结果,第一个参数表示的是当前已经聚合起来的map。
07:25
那初始是MAP2,那之后呢,要更新里边对应的值,所以我们把这个叫做for map,然后另外一个参数呢,即使是本立MAP1里边的所有元素依次去做处理,那所以这里边其实就是一个K,对嘛,我们直接就把它叫做KV下来我们就可以直接取出KV里边的K和value_一是K,那么。Value自然就是KV里边的下划线。二、先把这个拿出来,接下来我们自然就是要判断当前的K是否在mer map当中,呃,这个判断的话,我们也可以直接把它合并在一起,就直接用mer map去call else当前的K值。
08:18
那大家会想到,如果我获取到的话,那就直接用当前的值去加上value对应的这个值就可以了吗?啊,因为当前这是我们MAP1里边对应的那个已经统计出来的个数,而。MAP2里边的个数呢,那自然就是从默map里边取出来的,那如果要有的话直接叠加起来,没有的话,那MAP1里边,呃,MAP2里边,我们这个状态里边的值以零做计算,叠加不就可以了吗?啊,那得到的值呢,最后再付给medu map对应的对应的那个value,所以我们再做一个对应的赋值操作,当然我们也可以调破的方法啊,我们这里用了那个简简写的形式,那最后我们要返回的,大家看这里边当前返回的还是unit类型的,我们得返回一个map嘛,所以就直接把当前的merged map返回就可以了。
09:20
哎,这个就是我们定义的这个过程。以整体来看的话,还是非常的清晰的,把这个处理的流程就是每一个MAP1里边的k value对都合并到当前的MAP2里边来,那这个合并的过程呢,是要判断它是否在里边,把它的value值要做一个叠加,而不是简单的覆盖。啊,那当然对于当前MAP3的类型,我们也可以看一下,其实是一个multipleable的map,因为最终返回的值不就是MAP2做更新之后的那个mer map吗?哎,所以当前自然就是一个multipleable.map然后我们可以把当前MAP3的值做一个打印。
10:08
我们可以看到最后得到的结果,首先D是只出现在MAP2里的,当然就这个值只是三,那另外其他的三个值呢,三个K2个map里边都出现了,A一个是一,一个是六,合并起来是七,B一个是三,一个是二,合并起来是五,那C的话一个是六,一个是九,合并起来是15,这就起到了我们真正能够合并两个map里边数值的这样一个目的。
我来说两句