水善利萬物而不爭(zhēng),處眾人之所惡,故幾于道??
目錄
??1. 過濾 - filter
??2. 轉(zhuǎn)換/映射 - map
??3. 扁平化 - flatten
??4. 扁平化+映射 - flatMap
??5. 分組 - groupBy
??6. 簡(jiǎn)化(規(guī)約) - reduce
??7. 折疊 - fold
??8. 函數(shù)小練習(xí)
1. 過濾 - filter
?遍歷一個(gè)集合并從中獲取滿足指定條件的元素組成一個(gè)新的集合//對(duì)List集合進(jìn)行遍歷,將偶數(shù)取出,放到新的集合中去
val list: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9)
println(list.filter((a: Int) => {a % 2 == 0}))
println(list.filter(_ % 2 == 0))
??filter()
方法的參數(shù)是一個(gè)函數(shù)類型,其返回值為布爾類型,函數(shù)體指明過濾的規(guī)則。
2. 轉(zhuǎn)換/映射 - map
?將集合中的每一個(gè)元素映射到某一個(gè)函數(shù)//將集合中的元素進(jìn)行乘2操作
println(list.map(_ * 2))
3. 扁平化 - flatten
?flatten
函數(shù)用于將嵌套的集合展平為一個(gè)單層的集合。它將嵌套的集合中的元素取出來,放入一個(gè)新的集合中。
?flatten
函數(shù)只對(duì)嵌套的集合有效,如果集合中的元素不是集合類型,則flatten函數(shù)不會(huì)有任何效果
?注意: :::
操作符用于連接兩個(gè)集合,它將兩個(gè)集合合并成一個(gè)新的集合。它接受右側(cè)的集合作為參數(shù),并將其添加到左側(cè)的集合之后。而flatten
函數(shù)用于將嵌套的集合展平為一個(gè)單層的集合。它們的功能和用途是不同的
val list1 = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9))
val newList1: List[Int] = list1.flatten
println(newList1)
結(jié)果:
List(1, 2, 3, 4, 5, 6, 7, 8, 9)
4. 扁平化+映射 - flatMap
?flatMap
相當(dāng)于先進(jìn)行map操作,再進(jìn)行flatten操作
val strings = List("hello atguigu", "hello jingjing", "qcln jingjing")
//常規(guī)實(shí)現(xiàn)
val stringses: List[Array[String]] = strings.map(_.split(" "))
println(stringses.flatten)
// 使用flatMap函數(shù)實(shí)現(xiàn)
val strings2: List[String] = strings.flatMap(_.split(" "))
println(strings2)
5. 分組 - groupBy
?按照指定的規(guī)則對(duì)集合的元素進(jìn)行分組
val nameList = List("jingjing", "banzhang", "banhua", "anqcln", "jinghua")
// 按元素首字母進(jìn)行分組
val charToStrings: Map[Char, List[String]] = nameList.groupBy(_.charAt(0))
println(charToStrings)
結(jié)果:
Map(b -> List(banzhang, banhua), j -> List(jingjing, jinghua), a -> List(anqcln))
進(jìn)階:修改分組后key的值
??直接再進(jìn)行一次map映射
// 將分組后key的值改為大寫
val keyStyle1: immutable.Iterable[String] = charToStrings.map(MapKv => {
val upperKey: Char = MapKv._1.toUpper
upperKey + " -- " + MapKv._2
})
println(keyStyle1)
// 將分組后key為b的值改為X
val keyStyle2: immutable.Iterable[String] = charToStrings.map(MapKV => {
val newKey = if (MapKV._1.equals('b')) 'X' else MapKV._1
newKey + " -- " + MapKV._2
})
println(keyStyle2)
??說明:Scala中if條件判斷其實(shí)是有返回值的,返回值取決于滿足條件的代碼體的最后一行內(nèi)容。
6. 簡(jiǎn)化(規(guī)約) - reduce
?通過指定的邏輯將集合中的數(shù)據(jù)進(jìn)行聚合,從而減少數(shù)據(jù),最終獲取結(jié)果
?reduce
:底層調(diào)用的是reduceLeft。他要求傳入的兩個(gè)參數(shù)的類型必須一致,返回值也是該類型。
?reduceLeft
:傳入的兩個(gè)參數(shù)的參數(shù)類型可以不一致。它從集合左邊開始做聚合,返回值類型是左邊的類型。
?reduceRight
:傳入的兩個(gè)參數(shù)的參數(shù)類型可以不一致。它從集合右邊開始做聚合,返回值類型是右邊的類型。
val list = List(1, 2, 3, 4)
val res: Int = list.reduce(_ + _)
val res: Int = list.reduceLeft(_ + _)
val res: Int = list.reduceRight(_ + _)
println(res)
println(list.reduceLeft(_ - _)) // -8
println(list.reduceRight(_ - _)) // -2
val list2: List[Int] = List(3, 4, 5, 8, 10)
println(list2.reduceRight(_ - _)) // 6
?reduceLeft
:從左邊開始簡(jiǎn)化,用第一個(gè)元素減去第二個(gè)元素,然后再用結(jié)果減去第三個(gè)元素
?reduceRight
:從右邊開始簡(jiǎn)化,用倒數(shù)第二個(gè)元素減去倒數(shù)第一個(gè)元素,再用倒數(shù)第三個(gè)元素減去上一個(gè)結(jié)果
從源碼角度理解reduceRight
的計(jì)算方法
7. 折疊 - fold
?簡(jiǎn)化的一種特殊情況,它是集合外元素和集合內(nèi)部元素進(jìn)行聚合。計(jì)算方式和簡(jiǎn)化相似。
val list2: List[Int] = List(3, 4, 5, 8, 10)
println(list2.fold(10)(_+_)) // 40
println(list2.foldLeft(11)(_ - _)) // -19
println(list2.foldRight(12)(_ - _)) // -6
?foldLeft
:從左邊開始折疊,用集合外的元素減去集合左邊第一個(gè)元素,再用結(jié)果減去第二個(gè)元素,以此類推
?foldRight
:從右邊開始折疊,用集合最后一個(gè)元素減去集合外的元素,再用集合倒數(shù)第二個(gè)元素減去結(jié)果,以此類推
8. 函數(shù)小練習(xí)
將兩個(gè)map集合中的數(shù)據(jù)合并(key相同的話,value相加)
val map1 = mutable.Map("a"->1, "b"->2, "c"->3)
val map2 = mutable.Map("a"->4, "b"->5, "d"->6)
//方法一
// map1("e") = 9 這樣也能添加元素....
val res: mutable.Map[String, Int] = map1.foldLeft(map2)(
// m2Jh表示map2,m1表示map1中的每一個(gè)元素
(m2Jh, m1) => {
// 指定合并的規(guī)則
val m1Key: String = m1._1
val m1Value: Int = m1._2
// 根據(jù)map1中元素的key更新map2中的value,或者直接添加
m2Jh(m1Key) = m2Jh.getOrElse(m1Key, 0) + m1Value
m2Jh
})
// ================================== 方法二 =================================
// 我寫的,通俗易懂
val res: mutable.Map[String, Int] = map1.foldLeft(map2)((m2Jh, m1) => {
val m1Key: String = m1._1
val m1Value: Int = m1._2
// 在map2中獲取value,如果獲取到,執(zhí)行update更新value,如果獲取不到執(zhí)行put添加
val flag: Int = m2Jh.getOrElse(m1Key, 0)
if(flag==0){
m2Jh.put(m1Key,m1Value)
}else{
m2Jh.update(m1Key,m1Value+flag)
}
m2Jh // 將map2集合返回,因?yàn)閒oldLeft()()的參數(shù)類型就要求的
})
println(res)
分析:
??兩個(gè)集合合并,涉及到兩個(gè)集合,用折疊fold
??折疊有三個(gè),具體選哪個(gè),fold
要求集合外部元素類型和集合內(nèi)部元素類型一致,foldLeft
和foldRight
可以不一致,這兩個(gè)集合合并的話,明顯類型不一致,因?yàn)榉椒ㄕ{(diào)用的時(shí)候把其中一個(gè)map集合整體作為參數(shù)傳了進(jìn)去,這個(gè)參數(shù)類型是map,而方法調(diào)用者是一個(gè)map集合,內(nèi)部元素的類型是一個(gè)元組,這一個(gè)元組,一個(gè)map類型明顯不一致,所以不能用fold,那就用foldLeft得了,簡(jiǎn)單。文章來源:http://www.zghlxwxcb.cn/news/detail-582634.html
??最后合并的思路是什么? 把其中一個(gè)map集合作為參數(shù)傳遞進(jìn)去,然后再迭代另一個(gè)集合的時(shí)候取到key和value判斷,如果這個(gè)key在集合中存在,那么更新它的value,如果這個(gè)key在集合中不存在,將這個(gè)key和value加入到這個(gè)集合中。文章來源地址http://www.zghlxwxcb.cn/news/detail-582634.html
到了這里,關(guān)于Scala集合常用函數(shù) - 高級(jí)計(jì)算函數(shù)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!