スカラのスライス関数を日本語で言い換えると:「スカラのスライス機能」

今日は、Scalaのslice関数について見てみましょう。

スカラスライス

以下のAPIクラスには、Scalaのスライス関数が利用可能です。

  • Scala Array API
  • String API
  • Scala Collection API

次のセクションでは、各APIを取り上げ、適切な例を使って詳しく議論します。

スカラのスライス関数の使用方法は:

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]

スライス関数のパラメーター: 「スライス」関数のパラメーターの使用方法は、以下の表に記載されています。

S.No. Function Params Usage
1. First Parameter Starting index (Inclusive). It should be zero or any any positive integer less than the length of the Collection or String or Array.
2. Second Parameter Ending index (Exclusive).

「スライス」関数は、要素の抽出を行います。最初のインデックス(含む)から、指定したインデックスまで(含まず)の要素が抽出されます。抽出の対象は、数値の配列、文字列の文字、コレクションのオブジェクトです。

スカラのアレイスライスを日本語で言い換えると「スカラ配列の一部分」です。

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)

上記の例で、利用可能なインデックスを超えて2番目のパラメーターの値を指定した場合(marksArrayの利用可能な最大インデックスは5で、長さは5であるため)、その値は無視され、利用可能なインデックスまでの結果のみが返されます。注意:Javaとは異なり、ArrayIndexOutOfBoundsExceptionは発生しません。

スカラコレクションのスライス

Scalaの標準APIでは、ほとんどのクラスがこのスライス関数を定義しており、インデックスベースの要素アクセスをサポートしています。たとえば、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のStringの一部を切り取る

Scala APIでは、「StringOps」というクラスがscala.collection.immutableパッケージに定義されています。以下に示すように、それはスライス機能を定義しています。

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

注意:Scalaでは、JavaのStringクラスを使用します。しかし、このクラスにはslice関数はありません。JavaのStringオブジェクトでslice関数を使用する場合、Scalaのコンパイラは内部でこのStringオブジェクトをStringOpsクラスオブジェクトに変換してからこのslice関数を使用します(slice関数だけでなく、他にも多くの機能があります。詳細はScala APIを参照してください)。つまり、「StringOps」はStringクラスの暗黙のクラスです。Stringのslice関数の例:

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

私たちは知っている通り、文字列のインデックスはゼロから始まります。ここで、from-index = 6 とは、until-index = 9 を意味します(しかし、これは除外されるため、インデックス 8 までを考慮する必要があります)。文字列の substring 関数は、以下に示すように slice 関数と同様に機能します。

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

ここでは、str.slice(6,9)とstr.substring(6,9)は同じ値を返しています。Stringクラスのsliceとsubstring関数の違い

  • Functionality wise and syntax wise there is no difference
  • Performance is almost similar and ignorable.

Scalaでは、以下に示すように、Stringの文字には配列要素と同じようにアクセスできます。

scala> str(0)
res0: Char = H

Charを返しますが、Stringではありません。

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 Doc

コメントを残す 0

Your email address will not be published. Required fields are marked *