- SCALA COLLECTIONS
- The main Scala collections classes
- THE ARRAYBUFFER CLASS
- More ways to work with `ArrayBuffer`
- THE LIST CLASS
- Creating Lists
- Adding elements to a List
- How to remember the method names
- How to loop over lists
- A little bit of history
- THE VECTOR CLASS
- THE MAP CLASS
- Creating a mutable Map
- Adding elements to a Map
- Removing elements from a Map
- Updating Map elements
- Traversing a Map
- See also
- THE SET CLASS
- Adding elements to a Set
- Deleting elements from a Set
- More Sets
- ANONYMOUS FUNCTIONS
- Examples
- Anonymous functions with the `filter` method
- Key points
- Bonus: Digging a little deeper
- COMMON SEQUENCE METHODS
- Note: The methods don’t mutate the collection
- Sample lists
- `map`
- `filter`
- `foreach`
- `head`
- `tail`
- `take`, `takeWhile`
- `drop`, `dropWhile`
- `reduce`
- Even more!
- COMMON MAP METHODS
- Mutable Map examples
- See also
原文地址 https://docs.scala-lang.org/overviews/scala-book/collections-101.html
如果您是从 Java 来到 Scala,那么您能做的最好的事情就是忘记 Java 集合类,并按照预期使用 Scala 集合类。 正如本书的一位作者所说,“根据个人经验,当我第一次开始使用 Scala 时,我试图在我的 Scala 代码中使用 Java 集合类,但这一切都减慢了我的进度。”
The main Scala collections classes您将定期使用的主要 Scala 集合类是:
ClassDescriptionArrayBuffer
一个索引的、可变的序列List
线性(链表),不可变序列Vector
一个索引的、不可变的序列Map
基础Map
(键/值对)类Set
基础Set
类
Map
和 Set
有可变和不可变版本。
我们将在以下课程中演示这些课程的基础知识。
在以下有关 Scala 集合类的课程中,无论何时我们使用不可变这个词,都可以安全地假设该类旨在用于函数式编程 (FP) 风格。 使用这些类,您无需修改集合; 您将函数方法应用于集合以创建新结果。 您将在以下示例中看到这意味着什么。
THE ARRAYBUFFER CLASShttps://docs.scala-lang.org/overviews/scala-book/arraybuffer-examples.html
如果您是一名从 Java 来到 Scala 的 OOP 开发人员,那么 ArrayBuffer 类可能最适合您,因此我们将首先演示它。 它是一个可变序列,所以你可以使用它的方法来修改它的内容,这些方法类似于 Java 序列上的方法。
要使用 ArrayBuffer,您必须首先导入它:
import scala.collection.mutable.ArrayBuffer
将其导入本地作用域后,您可以像这样创建一个空的 ArrayBuffer:
val ints = ArrayBuffer[Int]()
val names = ArrayBuffer[String]()
拥有 ArrayBuffer 后,您可以通过多种方式向其中添加元素:
val ints = ArrayBuffer[Int]()
ints += 1
ints += 2
The REPL shows how +=
works:
scala> ints += 1
res0: ints.type = ArrayBuffer(1)
scala> ints += 2
res1: ints.type = ArrayBuffer(1, 2)
这只是创建 ArrayBuffer 并向其添加元素的一种方法。 您还可以创建一个带有初始元素的 ArrayBuffer,如下所示:
val nums = ArrayBuffer(1, 2, 3)
您可以通过以下几种方法向此 ArrayBuffer 添加更多元素:
val nums = ArrayBuffer(1, 2, 3)
您可以通过以下几种方法向此 ArrayBuffer 添加更多元素:
// add one element
nums += 4
// add multiple elements
nums += 5 += 6
// add multiple elements from another collection
nums ++= List(7, 8, 9)
您可以使用 -=
和 --=
方法从 ArrayBuffer
中删除元素:
// remove one element
nums -= 9
// remove multiple elements
nums -= 7 -= 8
// remove multiple elements using another collection
nums --= Array(5, 6)
下是所有这些示例在 REPL 中的样子:
scala> import scala.collection.mutable.ArrayBuffer
scala> val nums = ArrayBuffer(1, 2, 3)
val nums: ArrayBuffer[Int] = ArrayBuffer(1, 2, 3)
scala> nums += 4
val res0: ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 4)
scala> nums += 5 += 6
val res1: ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 4, 5, 6)
scala> nums ++= List(7, 8, 9)
val res2: ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 4, 5, 6, 7, 8, 9)
scala> nums -= 9
val res3: ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 4, 5, 6, 7, 8)
scala> nums -= 7 -= 8
val res4: ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 4, 5, 6)
scala> nums --= Array(5, 6)
val res5: ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 4)
More ways to work with ArrayBuffer
为简要概述,以下是您可以与 ArrayBuffer 一起使用的几种方法:
val a = ArrayBuffer(1, 2, 3) // ArrayBuffer(1, 2, 3)
a.append(4) // ArrayBuffer(1, 2, 3, 4)
a.append(5, 6) // ArrayBuffer(1, 2, 3, 4, 5, 6)
a.appendAll(Seq(7,8)) // ArrayBuffer(1, 2, 3, 4, 5, 6, 7, 8)
a.clear // ArrayBuffer()
val a = ArrayBuffer(9, 10) // ArrayBuffer(9, 10)
a.insert(0, 8) // ArrayBuffer(8, 9, 10)
a.insertAll(0, Vector(4, 5, 6, 7)) // ArrayBuffer(4, 5, 6, 7, 8, 9, 10)
a.prepend(3) // ArrayBuffer(3, 4, 5, 6, 7, 8, 9, 10)
a.prepend(1, 2) // ArrayBuffer(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
a.prependAll(Array(0)) // ArrayBuffer(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val a = ArrayBuffer.range('a', 'h') // ArrayBuffer(a, b, c, d, e, f, g)
a.remove(0) // ArrayBuffer(b, c, d, e, f, g)
a.remove(2, 3) // ArrayBuffer(b, c, g)
val a = ArrayBuffer.range('a', 'h') // ArrayBuffer(a, b, c, d, e, f, g)
a.trimStart(2) // ArrayBuffer(c, d, e, f, g)
a.trimEnd(2) // ArrayBuffer(c, d, e)
THE LIST CLASS
https://docs.scala-lang.org/overviews/scala-book/list-class.html
List 类是一个线性的、不可变的序列。 所有这一切都意味着它是一个无法修改的链表。 任何时候您想要添加或删除 List 元素,您都可以从现有 List 创建一个新 List。
Creating Lists这是您创建初始列表的方式:
val ints = List(1, 2, 3)
val names = List("Joel", "Chris", "Ed")
如果您愿意,您也可以声明 List 的类型,但通常没有必要:
val ints: List[Int] = List(1, 2, 3)
val names: List[String] = List("Joel", "Chris", "Ed")
Adding elements to a List
因为 List 是不可变的,所以你不能向它添加新元素。 相反,您可以通过在现有列表中添加或添加元素来创建新列表。 例如,给定这个列表:
val a = List(1,2,3)
您将元素添加到列表中,如下所示:
val b = 0 +: a
val b = List(-1, 0) ++: a
REPL 展示了这是如何工作的:
scala> val b = 0 +: a
b: List[Int] = List(0, 1, 2, 3)
scala> val b = List(-1, 0) ++: a
b: List[Int] = List(-1, 0, 1, 2, 3)
您也可以将元素附加到 List,但是因为 List 是一个单向链表,所以您应该只在它前面添加元素; 向其中添加元素是一个相对较慢的操作,尤其是在处理大型序列时。
提示:如果您想在不可变序列中添加和附加元素,请改用 Vector。
因为 List 是一个链表类,你不应该尝试通过索引值访问大列表的元素。 例如,如果您有一个包含一百万个元素的 List,那么访问像 myList(999999) 这样的元素将需要很长时间。 如果要访问这样的元素,请改用 Vector 或 ArrayBuffer。
How to remember the method names如今,IDE 为我们提供了极大的帮助,但是记住这些方法名称的一种方法是认为 : 字符代表序列所在的一侧,因此当您使用 +: 时,您知道列表需要在右侧 , 像这样:
0 +: a
同样,当您使用 :+ 时,您知道列表需要在左侧:
a :+ 4
有更多的技术方法可以考虑这一点,这可以是一种记住方法名称的简单方法。
这些方法名称的一个好处是:它们是一致的。 相同的方法名称用于其他不可变序列类,例如 Seq 和 Vector。
How to loop over lists我们在本书前面展示了如何循环列表,但值得再次展示语法。 给定一个这样的列表:
val names = List("Joel", "Chris", "Ed")
您可以像这样打印每个字符串:
for (name for (name val list = 1 :: 2 :: 3 :: Nil
list: List[Int] = List(1, 2, 3)
这是有效的,因为 List 是一个以 Nil 元素结尾的单向链表。
THE VECTOR CLASShttps://docs.scala-lang.org/overviews/scala-book/vector-class.html
Vector 类是一个索引的、不可变的序列。 描述的“索引”部分意味着您可以通过索引值非常快速地访问 Vector 元素,例如访问 listOfPeople(999999)。
一般来说,除了 Vector 有索引而 List 没有索引的区别外,这两个类的工作方式相同,因此我们将快速浏览这些示例。
以下是创建 Vector 的几种方法:
val nums = Vector(1, 2, 3, 4, 5)
val strings = Vector("one", "two")
val peeps = Vector(
Person("Bert"),
Person("Ernie"),
Person("Grover")
)
因为 Vector 是不可变的,所以你不能向它添加新元素。 相反,您可以通过向现有 Vector 附加或预先添加元素来创建新序列。 例如,给定这个向量:
val a = Vector(1,2,3)
你附加这样的元素:
val b = a :+ 4
val b = a ++ Vector(4, 5)
The REPL shows how this works:
scala> val a = Vector(1,2,3)
a: Vector[Int] = Vector(1, 2, 3)
scala> val b = a :+ 4
b: Vector[Int] = Vector(1, 2, 3, 4)
scala> val b = a ++ Vector(4, 5)
b: Vector[Int] = Vector(1, 2, 3, 4, 5)
您还可以预先添加这样的元素:
val b = 0 +: a
val b = Vector(-1, 0) ++: a
REPL 再次展示了这是如何工作的:
scala> val b = 0 +: a
b: Vector[Int] = Vector(0, 1, 2, 3)
scala> val b = Vector(-1, 0) ++: a
b: Vector[Int] = Vector(-1, 0, 1, 2, 3)
因为 Vector 不是链表(如 List),您可以在其前面添加和附加元素,并且两种方法的速度应该相似。
最后,您可以像处理 ArrayBuffer 或 List 一样遍历 Vector 中的元素:
scala> val names = Vector("Joel", "Chris", "Ed")
val names: Vector[String] = Vector(Joel, Chris, Ed)
scala> for (name "Alaska",
"IL" -> "Illinois",
"KY" -> "Kentucky"
)
Scala 有可变和不可变的 Map 类。 在本课中,我们将展示如何使用可变类。
Creating a mutable Map要使用可变 Map 类,首先导入它:
import scala.collection.mutable.Map
然后你可以像这样创建一个Map:
val states = collection.mutable.Map("AK" -> "Alaska")
Adding elements to a Map
现在您可以使用 +=
向 Map 添加单个元素,如下所示:
states += ("AL" -> "Alabama")
您还可以使用 +=
添加多个元素:
states += ("AR" -> "Arkansas", "AZ" -> "Arizona")
您可以使用 ++= 从另一个 Map 添加元素:
states ++= Map("CA" -> "California", "CO" -> "Colorado")
The REPL shows how these examples work:
scala> val states = collection.mutable.Map("AK" -> "Alaska")
states: scala.collection.mutable.Map[String,String] = Map(AK -> Alaska)
scala> states += ("AL" -> "Alabama")
res0: states.type = Map(AL -> Alabama, AK -> Alaska)
scala> states += ("AR" -> "Arkansas", "AZ" -> "Arizona")
res1: states.type = Map(AZ -> Arizona, AL -> Alabama, AR -> Arkansas, AK -> Alaska)
scala> states ++= Map("CA" -> "California", "CO" -> "Colorado")
res2: states.type = Map(CO -> Colorado, AZ -> Arizona, AL -> Alabama, CA -> California, AR -> Arkansas, AK -> Alaska)
Removing elements from a Map
您可以使用 -= 和 --= 并指定键值从 Map 中删除元素,如以下示例所示:
states -= "AR"
states -= ("AL", "AZ")
states --= List("AL", "AZ")
The REPL shows how these examples work:
scala> states -= "AR"
res3: states.type = Map(CO -> Colorado, AZ -> Arizona, AL -> Alabama, CA -> California, AK -> Alaska)
scala> states -= ("AL", "AZ")
res4: states.type = Map(CO -> Colorado, CA -> California, AK -> Alaska)
scala> states --= List("AL", "AZ")
res5: states.type = Map(CO -> Colorado, CA -> California, AK -> Alaska)
Updating Map elements
您可以通过将它们的键重新分配给新值来更新 Map 元素:
states("AK") = "Alaska, A Really Big State"
The REPL shows the current Map
state:
scala> states("AK") = "Alaska, A Really Big State"
scala> states
res6: scala.collection.mutable.Map[String,String] = Map(CO -> Colorado, CA -> California, AK -> Alaska, A Really Big State)
Traversing a Map
有几种不同的方法可以迭代映射中的元素。Given a sample map:
val ratings = Map(
"Lady in the Water"-> 3.0,
"Snakes on a Plane"-> 4.0,
"You, Me and Dupree"-> 3.5
)
循环遍历所有地图元素的一个好方法是使用for
循环语法:
for ((k,v) println(s"key: $movie, value: $rating")
}
See also
还有其他方法可以使用 Scala Maps,以及满足不同需求的 Map 类的一个很好的集合。 有关更多信息和示例,请参阅 Map 类文档。
THE SET CLASShttps://docs.scala-lang.org/overviews/scala-book/set-class.html
Scala Set 类是一个没有重复元素的可迭代集合。
Scala 有可变和不可变的 Set 类。 在本课中,我们将展示如何使用可变类。
Adding elements to a Set要使用可变 Set,首先导入它:
val set = scala.collection.mutable.Set[Int]()
您可以使用 +=、++= 和 add 方法将元素添加到可变 Set 中。 这里有一些例子:
set += 1
set += 2 += 3
set ++= Vector(4, 5)
The REPL shows how these examples work:
scala> val set = scala.collection.mutable.Set[Int]()
val set: scala.collection.mutable.Set[Int] = Set()
scala> set += 1
val res0: scala.collection.mutable.Set[Int] = Set(1)
scala> set += 2 += 3
val res1: scala.collection.mutable.Set[Int] = Set(1, 2, 3)
scala> set ++= Vector(4, 5)
val res2: scala.collection.mutable.Set[Int] = Set(1, 5, 2, 3, 4)
请注意,如果您尝试向已经在其中的集合添加一个值,该尝试将被悄悄忽略:
scala> set += 2
val res3: scala.collection.mutable.Set[Int] = Set(1, 5, 2, 3, 4)
Set 也有一个 add 方法,如果元素被添加到集合中,则返回 true,如果没有添加,则返回 false。 REPL 展示了它是如何工作的:
scala> set.add(6)
res4: Boolean = true
scala> set.add(5)
res5: Boolean = false
Deleting elements from a Set
使用 -= 和 --= 方法从集合中删除元素,如以下示例所示:
scala> val set = scala.collection.mutable.Set(1, 2, 3, 4, 5)
set: scala.collection.mutable.Set[Int] = Set(2, 1, 4, 3, 5)
// one element
scala> set -= 1
res0: scala.collection.mutable.Set[Int] = Set(2, 4, 3, 5)
// two or more elements (-= has a varargs field)
scala> set -= (2, 3)
res1: scala.collection.mutable.Set[Int] = Set(4, 5)
// multiple elements defined in another sequence
scala> set --= Array(4,5)
res2: scala.collection.mutable.Set[Int] = Set()
有更多使用集合的方法,包括 clear 和 remove,如以下示例所示:
scala> val set = scala.collection.mutable.Set(1, 2, 3, 4, 5)
set: scala.collection.mutable.Set[Int] = Set(2, 1, 4, 3, 5)
// clear
scala> set.clear()
scala> set
res0: scala.collection.mutable.Set[Int] = Set()
// remove
scala> val set = scala.collection.mutable.Set(1, 2, 3, 4, 5)
set: scala.collection.mutable.Set[Int] = Set(2, 1, 4, 3, 5)
scala> set.remove(2)
res1: Boolean = true
scala> set
res2: scala.collection.mutable.Set[Int] = Set(1, 4, 3, 5)
scala> set.remove(40)
res3: Boolean = false
More Sets
Scala 还有几个 Set 类,包括 SortedSet、LinkedHashSet 等。 有关这些类的更多详细信息,请参阅 Set 类文档。
ANONYMOUS FUNCTIONShttps://docs.scala-lang.org/overviews/scala-book/anonymous-functions.html
在本书前面,你看到你可以像这样创建一个整数列表:
val ints = List(1,2,3)
当你想创建一个更大的列表时,你也可以使用 List 类的 range 方法创建它们,如下所示:
val ints = List.range(1, 10)
该代码将整数创建为一个整数列表,其值范围从 1 到 10。您可以在 REPL 中看到结果:
scala> val ints = List.range(1, 10)
x: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9)
在本课中,我们将使用这样的列表来演示称为匿名函数的函数式编程特性。 在我们演示最常见的 Scala 集合方法之前,这将有助于理解这些是如何工作的。
Examples匿名函数就像一个小函数。 例如,给定这样的列表:
val ints = List(1,2,3)
您可以通过将 ints 中的每个元素加倍来创建一个新列表,如下所示:
val doubledInts = ints.map(_ * 2)
This is what that example looks like in the REPL:
scala> val doubledInts = ints.map(_ * 2)
doubledInts: List[Int] = List(2, 4, 6)
如图所示,doubledInts 现在是列表 List(2, 4, 6)。 在这个例子中,这段代码是一个匿名函数:
_ * 2
这是“将一个元素乘以 2”的简写方式。
熟悉 Scala 后,这是编写匿名函数的常用方法,但如果您愿意,也可以使用更长的形式编写它们。 除了像这样编写代码:
val doubledInts = ints.map(_ * 2)
或
val doubledInts = ints.map((i: Int) => i * 2)
val doubledInts = ints.map(i => i * 2)
所有三行都具有完全相同的含义:将 ints 中的每个元素加倍以创建一个新列表 doubledInts。
Scala 中的 _
字符是通配符。 你会看到它在几个不同的地方使用。 在这种情况下,它是“列表中的一个元素,整数”的简写方式。
在进一步讨论之前,值得一提的是,这个地图示例相当于这个 Java 代码:
List ints = new ArrayList(Arrays.asList(1, 2, 3));
// the `map` process
List doubledInts = ints.stream()
.map(i -> i * 2)
.collect(Collectors.toList());
显示的Map示例也与此 Scala 代码相同:
val doubledInts = for (i 5)
这是创建一个值都小于 5 的新列表的方法:
val x = ints.filter(_ i % 2 == 0)
val x = ints.filter(i => i % 2 == 0)
This is what the previous examples look like in the REPL:
scala> val x = ints.filter(_ > 5)
x: List[Int] = List(6, 7, 8, 9)
scala> val x = ints.filter(_ val x = ints.filter(_ % 2 == 0)
x: List[Int] = List(2, 4, 6, 8)
Key points
The key points of this lesson are:
- 您可以将匿名函数编写为一小段代码
- 您可以将它们与
List
类上的方法一起使用,例如map
和filter
- 使用这些小代码片段和强大的方法,您可以用很少的代码创建很多功能
Scala 集合类包含许多方法,如map
和filter
,它们是创建极具表现力的代码的强大方法。
您可能想知道 map
和 filter
示例是如何工作的。 简短的回答是,当在整数列表上调用 map
时——更准确地说是 List[Int]
——map
期望接收一个将一个 Int
值转换为另一个 Int
值的函数 . 因为 map
需要一个函数(或方法)将一个 Int
转换为另一个 Int
,所以这种方法也有效:该示例的最后两行与此相同:
val ints = List(1,2,3)
def double(i: Int): Int = i * 2 //a method that doubles an Int
val doubledInts = ints.map(double)
该示例的最后两行与此相同:
val doubledInts = ints.map(_ * 2)
类似地,当在 List[Int] 上调用时,filter 方法期望接收一个函数,该函数接受一个 Int 并返回一个布尔值。 因此,给定一个定义如下的方法:
def lessThanFive(i: Int): Boolean = if (i val doubles = nums.map(_ * 2)
doubles: List[Int] = List(2, 4, 6, 8, 10, 12, 14, 16, 18, 20)
正如我们在匿名函数课程中所展示的,您也可以像这样编写匿名函数:
scala> val doubles = nums.map(i => i * 2)
doubles: List[Int] = List(2, 4, 6, 8, 10, 12, 14, 16, 18, 20)
但是,在本课中,我们将始终使用第一种较短的形式。
有了这个背景,下面是一个应用到 nums
和 names
列表的map
方法的例子:
scala> val capNames = names.map(_.capitalize)
capNames: List[String] = List(Joel, Ed, Chris, Maurice)
scala> val doubles = nums.map(_ * 2)
doubles: List[Int] = List(2, 4, 6, 8, 10, 12, 14, 16, 18, 20)
scala> val lessThanFive = nums.map(_ < 5)
lessThanFive: List[Boolean] = List(true, true, true, true, false, false, false, false, false, false)
正如最后一个例子所示,使用 map 返回一个与原始类型 (List[Int]) 不同类型 (List[Boolean]) 的列表是完全合法的(并且非常常见)。
filter
filter 方法从给定的列表中创建一个新的过滤列表。 这里有一些例子:
scala> val lessThanFive = nums.filter(_ < 5)
lessThanFive: List[Int] = List(1, 2, 3, 4)
scala> val evens = nums.filter(_ % 2 == 0)
evens: List[Int] = List(2, 4, 6, 8, 10)
scala> val shortNames = names.filter(_.length names.foreach(println)
joel
ed
chris
maurice
nums 列表有点长,因此您可能不想打印出所有这些元素。 但是 Scala 方法的一个优点是您可以将方法链接在一起来解决这样的问题。 例如,这是从 nums 打印前三个元素的一种方法:
nums.filter(_ < 4).foreach(println)
The REPL shows the result:
scala> nums.filter(_ < 4).foreach(println)
1
2
3
head
head 方法来自 Lisp 和函数式编程语言。 它用于打印列表的第一个元素(头元素):
scala> nums.head
res0: Int = 1
scala> names.head
res1: String = joel
因为 String 是一个字符序列,您也可以将其视为一个列表。 这是 head 在这些字符串上的工作方式:
scala> "foo".head
res2: Char = f
scala> "bar".head
res3: Char = b
head 是一个很好的工作方法,但作为一个警告,它在调用空集合时也可能抛出异常:
scala> val emptyList = List[Int]()
val emptyList: List[Int] = List()
scala> emptyList.head
java.util.NoSuchElementException: head of empty list
tail
tail 方法也来自 Lisp 和函数式编程语言。 它用于打印列表中 head 元素之后的每个元素。 几个例子:
scala> nums.tail
res0: List[Int] = List(2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> names.tail
res1: List[String] = List(ed, chris, maurice)
就像 head 一样,tail 也适用于字符串:
scala> "foo".tail
res2: String = oo
scala> "bar".tail
res3: String = ar
请注意,与 head 和 tail 一样,在空集合上调用时也会抛出异常:
scala> emptyList.tail
java.lang.UnsupportedOperationException: tail of empty list
take
, takeWhile
take 和 takeWhile 方法为您提供了一种从列表中取出要创建新列表的元素的好方法。 这是保留式获取:
scala> nums.take(1)
res0: List[Int] = List(1)
scala> nums.take(2)
res1: List[Int] = List(1, 2)
scala> names.take(1)
res2: List[String] = List(joel)
scala> names.take(2)
res3: List[String] = List(joel, ed)
And this is takeWhile
:
scala> nums.takeWhile(_ < 5)
res4: List[Int] = List(1, 2, 3, 4)
scala> names.takeWhile(_.length < 5)
res5: List[String] = List(joel, ed)
drop
, dropWhile
drop 和 dropWhile 本质上是 take 和 takeWhile 的对立面。 这是删除式获取:
scala> nums.drop(1)
res0: List[Int] = List(2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> nums.drop(5)
res1: List[Int] = List(6, 7, 8, 9, 10)
scala> names.drop(1)
res2: List[String] = List(ed, chris, maurice)
scala> names.drop(2)
res3: List[String] = List(chris, maurice)
And this is dropWhile
:
scala> nums.dropWhile(_ < 5)
res4: List[Int] = List(5, 6, 7, 8, 9, 10)
scala> names.dropWhile(_ != "chris")
res5: List[String] = List(chris, maurice)
reduce
当你听到“map reduce”这个词时,reduce
部分指的是像reduce这样的方法。 它接受一个函数(或匿名函数)并将该函数应用于列表中的连续元素。
解释 reduce 的最好方法是创建一个可以传递给它的小助手方法。 例如,这是一个将两个整数相加的 add 方法,并且还为我们提供了一些不错的调试输出:
def add(x: Int, y: Int): Int = {
val theSum = x + y
println(s"received $x and $y, their sum is $theSum")
theSum
}
现在,鉴于该方法和此列表:
al a = List(1,2,3,4)
当你将 add 方法传递给 reduce 时会发生什么:
scala> a.reduce(add)
received 1 and 2, their sum is 3
received 3 and 3, their sum is 6
received 6 and 4, their sum is 10
res0: Int = 10
如该结果所示,reduce
使用 add
将列表 a
减少为单个值,在本例中为列表中整数的总和。
一旦你习惯了reduce,你就会写一个像这样的“求和”算法:
scala> a.reduce(_ + _)
res0: Int = 10
类似地,这就是“产品”算法的样子:
scala> a.reduce(_ * _)
res1: Int = 24
如果您以前从未见过它,那可能会有点令人兴奋,但过一段时间您就会习惯它。
在继续之前,了解 reduce 的一个重要部分是——顾名思义——它用于将集合减少到单个值。
Even more!Scala 序列类实际上有数十种附加方法,它们将使您无需编写另一个 for 循环。 但是,由于这是一本简单的介绍书,因此不会在此处全部介绍。 有关更多信息,see the collections overview of sequence traits.。
COMMON MAP METHODShttps://docs.scala-lang.org/overviews/scala-book/collections-maps.html
在本课中,我们将演示一些最常用的 Map 方法。 在这些最初的例子中,我们将使用一个不可变的 Map,Scala 也有一个可变的 Map 类,您可以就地修改它,本课稍后会演示。
对于这些示例,我们不会将 Map 方法分解为单独的部分; 我们将在每种方法之前提供一个简短的评论。
Given this immutable Map
:
val m = Map(
1 -> "a",
2 -> "b",
3 -> "c",
4 -> "d"
)
以下是该 Map 可用的一些方法示例:
// how to iterate over Map elements
scala> for ((k,v) val keys = m.keys
keys: Iterable[Int] = Set(1, 2, 3, 4)
// how to get the values from a Map
scala> val values = m.values
val values: Iterable[String] = MapLike.DefaultValuesIterable(a, b, c, d)
// how to test if a Map contains a key
scala> val contains3 = m.contains(3)
contains3: Boolean = true
// how to transform Map values
scala> val ucMap = m.transform((k,v) => v.toUpperCase)
ucMap: scala.collection.immutable.Map[Int,String] = Map(1 -> A, 2 -> B, 3 -> C, 4 -> D)
// how to filter a Map by its keys
scala> val twoAndThree = m.view.filterKeys(Set(2,3)).toMap
twoAndThree: scala.collection.immutable.Map[Int,String] = Map(2 -> b, 3 -> c)
// how to take the first two elements from a Map
scala> val firstTwoElements = m.take(2)
firstTwoElements: scala.collection.immutable.Map[Int,String] = Map(1 -> a, 2 -> b)
请注意,最后一个示例可能仅对已排序的 Map 有意义。
Mutable Map examples以下是可变 Map 类上可用的一些方法示例。 鉴于这个初始可变Map
val states = scala.collection.mutable.Map(
"AL" -> "Alabama",
"AK" -> "Alaska"
)
Here are some things you can do with a mutable Map
:
// add elements with +=
states += ("AZ" -> "Arizona")
states ++= Map("CO" -> "Colorado", "KY" -> "Kentucky")
// remove elements with -=
states -= "KY"
states --= List("AZ", "CO")
// update elements by reassigning them
states("AK") = "Alaska, The Big State"
// filter elements by supplying a function that operates on
// the keys and/or values
states.filterInPlace((k,v) => k == "AK")
See also
你可以用Map做更多的事情。 有关更多详细信息和示例,请参阅 Map 类文档。