十個驚人的Scala集合操作函數(shù)

十個驚人的Scala集合操作函數(shù)
當我操作 Scala 集合時惩阶,我一般會進行兩類操作:轉(zhuǎn)換操作(transformation )和行動操作(actions)(有些人喜歡叫他為聚合操作)。第一種操作類型將集合轉(zhuǎn)換為另一個集合,第二種操作類型返回某些類型的值事镣。

本文我將集中介紹幾個日常工作必備的 [Scala(https://www.iteblog.com/archives/tag/scala/) 集合函數(shù),如轉(zhuǎn)換函數(shù)和聚合函數(shù)焊夸。文章最后苛败,我會展示如何結(jié)合這些函數(shù)以解決具體問題。

文章目錄
· 1?最大值和最小值

· 2?Filter

· 3?Flatten

· 4?歐拉圖函數(shù)(Euler Diagram函數(shù))

· 5?map列表元素

· 6?flatMap

· 7?對整個集合進行條件檢查

· 8?對集合進行分組

· 9?Fold

· 10?您最喜歡的函數(shù)

· 11?總結(jié)

十個驚人的scala集合操作函數(shù)
https://www.iteblog.com/archives/1946.html

最大值和最小值
  我們先從動作函數(shù)(
action function)開始镰矿。在序列中查找最大或最小值是一個極常見的需求琐驴,較常用于面試問題和算法。還記得 Java 中的代碼行嗎?如下:

int[] arr = {11, 2, 5, 1, 6, 3, 9};

int to = arr.length - 1;

int max = arr[0];

for (int i = 0; i < to; i++) {

    if (max < arr[i+1])

        max = arr[i+1];

}

  

System.out.println(max);

問題:怎么在List 中找到最大/最小值呢绝淡?

Scala 推薦了一個很贊的解決方案:

val numbers = Seq(11, 2, 5, 1, 6, 3, 9) 

 numbers.max //11 

numbers.min //1

但實際操作的數(shù)據(jù)更加復雜宙刘。下面我們介紹一個更高級的例子,其中包含一個書的序列(查看源代碼案例)牢酵。

case class Book(title: String, pages: Int)

 val books = Seq(

  Book("Future of Scala developers", 85),

  Book("Parallel algorithms", 240),

  Book("Object Oriented Programming", 130),

  Book("Mobile Development", 495)

)

  

//Book(Mobile Development,495)

books.maxBy(book => book.pages)

  

//Book(Future of Scala developers,85)

books.minBy(book => book.pages)

如上所示悬包,
minBy & maxBy方法解決了復雜數(shù)據(jù)的問題。你只需選擇決定數(shù)據(jù)最大或最小的屬性馍乙。

Filter
你過濾過集合嗎布近?比如,篩選價格大于10美元的條目丝格,或挑選年齡在24歲以下員工等撑瞧,所有這些操作屬于過濾。
讓我們舉例說明:過濾一個數(shù)字List显蝌,只獲取奇數(shù)的元素预伺。

val numbers = Seq(1,2,3,4,5,6,7,8,9,10)

 numbers.filter(n **=**> n **%** 2 **==** 0)

然后加大難度,我想獲取頁數(shù)大于
120頁的書曼尊。

val books = Seq(

  Book("Future of Scala developers", 85),

  Book("Parallel algorithms", 240),

  Book("Object Oriented Programming", 130),

  Book("Mobile Development", 495)

)

  

books.filter(book => book.pages >= 120)

實際上酬诀,過濾是一個轉(zhuǎn)換類型的方法,但是比運用min和max方法簡單骆撇。

還有一個與filter類似的方法是filterNot料滥。它的名字就體現(xiàn)了它的作用。如果你還是不了解它的實際用途艾船,你可以在一個示例中葵腹,用filterNot替換filter 方法。

Flatten
我想大多數(shù)朋友都沒聽說過這個功能屿岂。其實它很好理解践宴,我們來舉例說明:

val abcd = Seq('a', 'b', 'c', 'd')

val efgj = Seq('e', 'f', 'g', 'h')

val ijkl = Seq('i', 'j', 'k', 'l')

val mnop = Seq('m', 'n', 'o', 'p')

val qrst = Seq('q', 'r', 's', 't')

val uvwx = Seq('u', 'v', 'w', 'x')

val yz = Seq('y', 'z')

val alphabet = Seq(abcd, efgj, ijkl, mnop, qrst, uvwx, yz)

// List(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z)

alphabet.flatten

當有一個集合的集合,然后你想對這些集合的所有元素進行操作時爷怀,就會用到
flatten阻肩。

歐拉圖函數(shù)(Euler Diagram函數(shù))
不要緊張!接下來的操作大家都熟知:差集运授、交集和并集烤惊。以下示例能很好地解釋
Euler Diagram 函數(shù):

val num1 = Seq(1, 2, 3, 4, 5, 6)

val num2 = Seq(4, 5, 6, 7, 8, 9)

//List(1, 2, 3)

num1.diff(num2)

//List(4, 5, 6)

num1.intersect(num2)

//List(1, 2, 3, 4, 5, 6, 4, 5, 6, 7, 8, 9)

num1.union(num2)

上述示例中的 union保留了重復的元素。如果我們不需要重復怎么辦吁朦?這時可以使用
distinct函數(shù):

//List(1, 2, 3, 4, 5, 6, 7, 8, 9)

num1.union(num2).distinct

下面是上述功能的圖示:

map列表元素
map 是 Scala 集合最常用的一個函數(shù)柒室。它的功能十分強大:

val numbers = Seq(1,2,3,4,5,6)

//List(2, 4, 6, 8, 10, 12)

numbers.map(n **=**> n * 2)

val chars = Seq('a', 'b', 'c', 'd')

//List(A, B, C, D)

chars.map(ch **=**> ch.toUpper)

map 函數(shù)的邏輯是遍歷集合中的元素并對每個元素調(diào)用函數(shù)。你也可以不調(diào)用任何函數(shù)逗宜,保持返回元素本身雄右,但這樣 map無法發(fā)揮作用空骚,因為你在映射過后得到的是同樣的集合。

flatMap
我很難具體說明flatMap 的使用場合擂仍,因為很多不同的情況下都會用到 flatMap囤屹。如果大家仔細觀察,就會發(fā)現(xiàn)flatMap 是由下列這兩個函數(shù)組成的:map & flatten
現(xiàn)在逢渔,假設我們想知道字母表中的大寫字母和小寫字母的排列情況:

val abcd = Seq('a', 'b', 'c', 'd')

//List(A, a, B, b, C, c, D, d)

abcd.flatMap(ch **=**> List(ch.toUpper, ch))

因為這篇文章是關于集合功能的介紹肋坚,所以此處略過
Future 和 Option 的示例。

對整個集合進行條件檢查
有一個場景大家都知道肃廓,即確保集合中所有元素都要符合某些要求智厌,如果有哪怕一個元素不符合條件,就需要進行一些處理:

val numbers = Seq(3, 7, 2, 9, 6, 5, 1, 4, 2)

//ture

numbers.forall(n **=**> n < 10)

//false

numbers.forall(n **=**> n > 5)

而forall 函數(shù)就是為處理這類需求而創(chuàng)建的亿昏。

對集合進行分組
你是否嘗試過將一個集合按一定的規(guī)則拆分成兩個新的集合?比如档礁,我們把某個集合拆分成偶數(shù)集和奇數(shù)集角钩,partition 函數(shù)可以幫我們做到這一點:

val numbers = Seq(3, 7, 2, 9, 6, 5, 1, 4, 2)

//(List(2, 6, 4, 2), List(3, 7, 9, 5, 1))

numbers.partition(n **=**> n **%** 2 **==** 0)

Fold
另一個流行的操作是fold。
在Scala 的上下文中呻澜,通车堇瘢可以考慮 foldLeft 和 foldRight。他們是從不同的方面做同樣的工作:

val numbers = Seq(1, 2, 3, 4, 5)

//15

numbers.foldLeft(0)((res, n) **=**> res + n)

在第一對括號中羹幸,我們放一個起始值脊髓。
在第二對括號中,我們定義需要對數(shù)字序列的每個元素執(zhí)行的操作栅受。
第一步将硝,n = 0,然后它根據(jù)序列元素變化屏镊。
另一個關于foldLeft 的例子依疼,計算字符數(shù):

val words = Seq("apple", "dog", "table")

//13

words.foldLeft(0)((resultLength, word) **=**> resultLength + word.length)

您最喜歡的函數(shù)
經(jīng)過了上面一系列的列舉,從Scala集合找到你最喜歡的函數(shù)是很酷的(cool)而芥。請大家在評論中寫下它律罢,并提供其使用的例子。

最近我通過了一個編譯測試棍丐,任務的內(nèi)容是:給你一個String S误辑,你需要找到包含大寫和小寫字符,但不包含數(shù)字的最長子字符串歌逢。
比如: dP4knqw1QAp
答案: QAp
那么我們?nèi)绾问褂肧cala集合函數(shù)來解決這個問題呢:

def theLongest(s: String): String = {

  s.split ("[0-9]")

    .filter (_.exists (ch => ch.isUpper))

    .filter (_.exists (ch => ch.isLower))

    .maxBy (_.length)

}

上面的函數(shù)解決了這個問題巾钉。如果輸入字符串不包含任何合適的子字符串,將會拋出
UnsupportedOperationException秘案。

總結(jié)
Scala具有令人難以置信的強大的集合API睛琳,你可以利用它做很多的事情盒蟆。 此外,相同的事情可以以不同的方式進行师骗,例如: 上面的歐拉函數(shù)例子历等。 Scala的API是很豐富的,我們需要很多時間和練習來學習它辟癌。

參考:
10 amazing scala collection functions

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末寒屯,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子黍少,更是在濱河造成了極大的恐慌寡夹,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件厂置,死亡現(xiàn)場離奇詭異菩掏,居然都是意外死亡,警方通過查閱死者的電腦和手機昵济,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進店門智绸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人访忿,你說我怎么就攤上這事瞧栗。” “怎么了海铆?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵迹恐,是天一觀的道長。 經(jīng)常有香客問我卧斟,道長殴边,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任珍语,我火速辦了婚禮找都,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘廊酣。我一直安慰自己能耻,他們只是感情好,可當我...
    茶點故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布亡驰。 她就那樣靜靜地躺著晓猛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪凡辱。 梳的紋絲不亂的頭發(fā)上戒职,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天,我揣著相機與錄音透乾,去河邊找鬼洪燥。 笑死磕秤,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的捧韵。 我是一名探鬼主播市咆,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼再来!你這毒婦竟也來了蒙兰?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤芒篷,失蹤者是張志新(化名)和其女友劉穎搜变,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體针炉,經(jīng)...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡挠他,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了篡帕。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片殖侵。...
    茶點故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖赂苗,靈堂內(nèi)的尸體忽然破棺而出愉耙,到底是詐尸還是另有隱情贮尉,我是刑警寧澤拌滋,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站猜谚,受9級特大地震影響败砂,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜魏铅,卻給世界環(huán)境...
    茶點故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一昌犹、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧览芳,春花似錦斜姥、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至悟泵,卻和暖如春杈笔,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背糕非。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工蒙具, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留球榆,地道東北人。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓禁筏,卻偏偏與公主長得像持钉,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子融师,可洞房花燭夜當晚...
    茶點故事閱讀 45,066評論 2 355

推薦閱讀更多精彩內(nèi)容