Scala切片函数完全指南:掌握slice()方法的用法与实例

这是文章《Scala的切片函数》的第1部分(共1部分)。

内容片段: 今天我们将研究Scala的切片函数。

Scala切片

以下API类中可用Scala的切片函数:

  • Scala数组API
  • 字符串API
  • Scala集合API

在下一部分中,我们将挑选每个API并以适当的示例进行深入讨论。

Scala使用切片函数的示例

Scala slice function
  def slice(from-index: Int, until-index: Int): ScalaAPIClass[A]

这里的”ScalaAPIClass”是指任何支持基于索引的访问(例如Seq、List等)的Scala集合类、String和Array类。例如:下面的函数在Scala API的Seq类中被定义。

  def slice(from-index: Int, until-index: Int): Seq[A]

切片功能参数:以下表格描述了”切片”功能参数的用法。

序号 函数参数 用法
1. 第一个参数 起始索引(包含)。它应该是零或任何小于集合、字符串或数组长度的正整数。
2. 第二个参数 结束索引(不包含)。

切片函数从”起始索引”(包含)提取元素,直到”终止索引”(不包含)。这里的元素可以是数组中的数字,字符串中的字符,或者集合中的对象。

Scala 数组切片

在Scala API中,Array类将切片函数定义如下:

def slice(from: Int, until: Int): Array[T]

在这里,’from’是数组的起始索引(包含),’until’是数组的结束索引(不包含)。数组切片函数示例:

scala> val marksArray = Array(56,79,60,99,71)
marksArray: Array[Int] = Array(56, 79, 60, 99, 71)

现在创建了一个包含5个值的整数数组,其索引开始的值为0,索引结束的值为4。它的长度为5。现在让我们来使用切片函数。

scala> marksArray.slice(0,2)
res0: Array[Int] = Array(56, 79)

从0索引开始,即第一个元素,并检索所有元素直到2,这意味着索引为1,所以我们在这里得到了第0个元素和第1个元素。

scala> marksArray.slice(3,4)
res1: Array[Int] = Array(99)

我们可以使用任何索引范围进行访问。

scala> marksArray.slice(3,3)
res2: Array[Int] = Array()

如果我们像上面那样给出相同的起始和结束值,我们会得到一个空数组,为什么?起始索引 = 3,结束索引 = 3 – 1 = 2,不可能从索引3到2之间检索一组元素对吧。

scala> marksArray.slice(-1,3)
res3: Array[Int] = Array(56, 79, 60)

如果我们给出负值,则索引值将从所示的可用索引开始。

scala> marksArray.slice(0,5)

res4: Array[Int] = Array(56, 79, 60, 99, 71)

如果我们在超出可用索引的范围内给出第二个参数的值,如上所示(marksArray的可用最大索引值仅为4,因为其长度为5),它将忽略该值并返回到可用索引为止。注意:与Java不同,它不会抛出任何ArrayIndexOutOfBoundsException异常。

Scala集合切片

在Scala的标准API中,大多数的类都定义了slice函数,用于支持基于索引的元素访问。例如,List类如下所示定义了这个函数。

def slice(from: Int, until: Int): List[A]

切片函数的示例:与数组示例相同,对于任何集合API,我们将获得相同的结果。

scala> val list = List(56, 79, 60, 99, 71)
list: List[Int] = List(56, 79, 60, 99, 71)

scala> list.slice(0,2)
res5: List[Int] = List(56, 79)

scala> list.slice(3,4)
res6: List[Int] = List(99)

scala> list.slice(3,3)
res7: List[Int] = List()

scala> list.slice(-1,3)
res8: List[Int] = List(56, 79, 60)

scala> list.slice(0,5)
res9: List[Int] = List(56, 79, 60, 99, 71)

如果我们访问一个空列表,我们只会得到一个空列表,如下所示。

scala> val list2 = List()
list2: List[Nothing] = List()

scala> list2.slice(0,1)

res10: List[Nothing] = List()

Scala的字符串切片

在Scala API中,”StringOps”类定义在scala.collection.immutable包中。它将slice函数定义如下所示:

def slice(from: Int, until: Int): String

注意:在Scala中,我们使用Java的String类。但是这个类没有切片函数。当我们在Java的String对象上使用切片函数时,Scala编译器会自动将该String对象转换为StringOps类对象,以使用该切片函数。(不仅有切片函数,还有其他函数。请参考Scala API获取更多信息。)这意味着”StringOps”是String类的一个隐式类。String切片函数的示例:

scala> val str = "Hello I'm doing good. How are you?"
str: String = Hello I'm doing good. How are you?

scala> str.slice(6,9)

res8: String = I'm

我们知道,在字符串中索引从零开始。这里的起始索引为6意味着结束索引为9(由于是排除性的,所以我们只需要考虑结束索引为8)。字符串的子串函数与切片函数的工作方式相同,如下所示:

scala> str.substring(6,9)
res12: String = I'm

这里的str.slice(6,9)和str.substring(6,9)都返回相同的值。slice与substring是String类中的函数,它们之间的区别是什么?

  • 在功能和语法方面没有区别
  • 性能几乎相似,差异可以忽略。

注意:在 Scala 中,我们可以像访问数组元素一样访问字符串的字符,如下所示:

scala> str(0)
res0: Char = H

这里返回的是一个字符,而不是一个字符串。

scala> str(-1)
java.lang.StringIndexOutOfBoundsException: String index out of range: -1
  at java.lang.String.charAt(String.java:658)
  at scala.collection.immutable.StringOps$.apply$extension(StringOps.scala:38)
  ... 33 elided

scala> str.length
res2: Int = 34

scala> str(34)
java.lang.StringIndexOutOfBoundsException: String index out of range: 34
  at java.lang.String.charAt(String.java:658)
  at scala.collection.immutable.StringOps$.apply$extension(StringOps.scala:38)

  ... 33 elided

请注意:如果我们尝试在超出范围的位置访问字符串的字符,就会出现StringIndexOutOfBoundsException异常,如上所示。字符串的字符访问返回Char,而substring和slice函数返回String,如下所示。

scala> str(0)
res4: Char = H

scala> str.substring(0,1)
res5: String = H

scala> str.slice(0,1)
res6: String = H

这就是关于”Scala的切片函数”使用的全部内容。在我的接下来的帖子中,我们将讨论更多的Scala概念。参考:Scala API文档。

bannerAds