Scala 片段2:List的操作符魔法
本文翻譯自:Scala snippets 2: List symbol magic
fairjm@ituring
Scala的每一個操作符都可以是函式,所以過載操作符(實際上不是真正的過載操作符,畢竟操作符都已經是方法了)是一件非常簡單並且在很多庫中都能看見的事。在這個片段中,我們將探討一些讓列表操作更加簡單的方法過載。
讓我們從++
操作符開始。首先,就像我們一直做的那樣,讓我們來建立一個列表:
scala> val list = 0 until 10 toList
list: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
scala> val list2 = 10 to 0 by -1 toList
list2: List[Int] = List(10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
然後大致瀏覽下來自 http://www.scala-lang.org/api/2.11.1/index.html#scala.collection.immutable.List 的一些操作:
第一個操作符是++
。我們可以用這個操作符把兩個列表連線在一起,並且返回一個新的列表:
scala> val list3 = list ++ list2
list3: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
scala> val list3 = list2 ++ list
list3: List[Int] = List(10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
注意你並不需要保證列表是相同型別的。Scala會自動選擇最相關的父類:
scala> val list1 = 0 to 10 toList
list1: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> val list2 = 10 to 0 by -1 toList
list2: List[Int] = List(10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
scala> val list3 = list1.asInstanceOf[List[Double]]
list3: List[Double] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> list3 ++ list2
res4: List[AnyVal] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
你可以看到最後的返回是AnyVal
型別的列表,這是對於Int
和Double
最常見的父類。
既然我們已經看過++
了,讓我們來看看和++
看起來最相似的++:
。這個操作符和++
有著相同的語義,不同的地方是結果的型別在++
中取決於左運算元而這個操作符取決於右運算元:
scala> vector1
res14: Vector[Int] = Vector(10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
scala> list1
res15: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> vector1 ++ list1
res16: scala.collection.immutable.Vector[Int] = Vector(10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> vector1 ++: list1
res17: List[Int] = List(10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
接下來的兩個操作符:+
和+:
可以讓我們向後和向前對列表增加新的元素:
scala> 999 +: list1
res27: List[Int] = List(999, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> list1 :+ 999
res28: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 999)
還有什麼?::
和:::
都是對列表之前增加一些東西的函式。::
操作符增加單個元素,而:::
操作符增加一個列表。所以基本上他們是和+:
和++
操作一樣的。主要的區別是+:
和++
可以被用於Traversable
,但::
和:::
只能用於列表。
scala> 11 +: list1
res38: List[Int] = List(11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> list1
res39: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> 11 +: list1
res40: List[Int] = List(11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> list2
res41: List[Int] = List(10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
scala> list1 ::: list2
res43: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
:\
和/:
用於摺疊操作(看這裡)。:\
從右至左摺疊,而/:
從左至右:
scala> list1
res50: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> (1 /: list1)((r,i) => {println(i);i+r})
0
1
2
3
4
5
6
7
8
9
10
res51: Int = 56
scala> (list1 :\ 1)((i,r) => {println(i);i+r})
10
9
8
7
6
5
4
3
2
1
0
res52: Int = 56
你可以看到摺疊的方向決定了元素是從前往後還是從後往前處理的。
這就是這個片段的全部。
相關文章
- Scala 片段3:列表的map,flatMap,zip和reduce
- 【Scala篇】--Scala中集合陣列,list,set,map,元祖陣列
- Scala學習 2 Scala物件導向物件
- scala片段4:使用型別類實現Pimp my library模式型別模式
- 探索Scala(2)-- TraitsAI
- Rxjava2操作符(二)RxJava
- Rxjava2操作符(三)RxJava
- 魔法轉換 (2千字)
- Scala學習筆記2筆記
- RxJava2 操作符總結RxJava
- 深入淺出RxJava(2):操作符RxJava
- 新手必備的常用 Android 程式碼片段整理(2)Android
- 集合框架-List集合-2框架
- Rxjava2操作符入門(一)RxJava
- Rxjava2的簡單使用與基本操作符RxJava
- 這不是魔法:Flask和@app.route(2)FlaskAPP
- 【Scala篇】--Scala中的函式函式
- Scala 技術週刊 | 第 2 期
- RxJava 知識梳理(2) RxJava2 操作符實戰RxJava
- Sublime 的 Snippets 快捷片段
- Scala學習(五)---Scala中的類
- RxJava2操作符學習筆記RxJava筆記
- 【Scala】Scala之ObjectObject
- [2]SpinalHDL教程——Scala簡單入門
- cocos2d-js攝像機跟隨的程式碼片段JS
- db2 list history 參考DB2
- DB2 prune 與 list historyDB2
- 有趣的 Scala 語言: 簡潔的 Scala 語法
- 收集的jQuery程式碼片段jQuery
- 神奇的Cookie互通魔法Cookie
- 程式碼片段
- 【Scala】Scala之TraitsAI
- 魔法逝
- Scala學習筆記(2)-基礎語法筆記
- Scala 學習筆記(2)之類和物件筆記物件
- RxJava2.X 學習筆記 -- 建立操作符RxJava筆記
- RxJava2原始碼分析(二):操作符原理分析RxJava原始碼
- RxJava2進階教程(一)——建立型操作符RxJava