コレクションとしてのString型
文字列のどこがコレクションなの?と思うかもしれませんが、
文字列は文字の集まりなのでコレクションとして捉えることができます。
実際、String型は単一の文字を表す型であるCharacter型のコレクションとして定義されており、
文字の列挙や文字数のカウントなどの機能を備えております。
Character型 とは
Character型とは先ほども記載しましたが、単一の文字を表す型になります。
一つ注意しなければならないのが、明示的にCharacterと定義しないと
型推論によりString型として宣言されてしまうという点です。
let string = "abc" // String型
let word = "a" // String型
let char: Character = "a" // Character型
String.Index型
String.Index型は、文字列内の位置を表す型になります。
String.Index型を用いることにより、
文字列内の特定の位置を指定しその位置に存在する文字にアクセスできます。
String.Index型の.
は、この型がString型の中にネストして定義されていることを表します。
ネストとは・・・あるものの中に、それと同じ形や種類の(一回り小さい)ものが入っている状態や構造のこと。ITの分野では、コンピュータプログラムやデータ構造において、ある構造の内部に同じ構造が含まれている状態のことを指す。
~ IT用語辞典より引用 ~
つまり、String型の中にIndexという型が存在しているということになります。
そのIndex型を参照するのにString.Indexと記述します。
.
は〜の
と認識するのがいいかもしれません。
StringのIndexという感じですね!
String.Index型の値は、String型の先頭位置を表すstartIndexプロパティや、
String型の末尾位置を表すendIndexプロパティなどを利用して取得します。
let string = "abc" // String型
let startIndex = string.startIndex // String.Index型
let endIndex = string.endIndex // String.Index型
String型からCharacter型の値を取り出すにはサブスクリプトを使用します。
インデックスにはString.Index型を指定します。
(サブスクリプトのインデックスとは[index]のindexの部分です!)
let string = "abc" (String型)
let char = string[string.startIndex] // "a" (Character型)
let string = "abc"
で、String型の文字列を宣言しています。
let char = string[string.startIndex]は、
まず初めに、string.startIndex
でString型の定数stringの先頭位置を取得してます。
この時のstring.startIndexは、String.Index型になります。
次に、string[string.startIndex]
でサブスクリプトにstring.startIndexを指定し、
定数stringの先頭の文字を取得しています。
それを最後に、let char = ・・・
の部分で定数charに代入しています。
endIndexプロパティは末尾のインデックスを取得をします。
ですが、末尾のインデックスとは最後の文字のインデックスではなく、
その次のインデックを示します。
なので、サブスクリプトのインデックスにendIndexを入れると実行時エラーになります。
let string = "abc" // String型
let char = string[string.endIndex] //実行時エラー
エラー内容:Fatal error: String index is out of bounds
和訳:致命的なエラー:文字列インデックスが範囲外です
先頭の文字を取得する方法はわかりましたが、
末尾の文字や、n番目の文字を取得するにはどうしたらいいか。
そんな悩みを解決してくれるメソッドがString型には備わっています。
それは、index(_:offsetBy:)
メソッドです。
index(_:offsetBy:)メソッドは、startIndexやendIndexが返す値をずらすことができます。
index(元になるインデックス(String.index型): ずらす位置(Int型))
で記述します。
let string = "abcde" // String型
let start = string.startIndex // String.Index型
let end = string.endIndex // String.Index型
//先頭から1つ後ろにずらす
let index1 = string.index(start, offsetBy: 1) // String.Index型
let b = string[index1] // b
//末尾から1つ前にずらす
let index2 = string.index(end, offsetBy: -1) // String.Index型
let e = string[index2] // e
また、最初に記載した通りString型は値の集合として表現されていますので、
for-in文を用いて全ての要素に順次アクセスすることが可能です。
let string = "abcde" // String型
//文字数のカウント
string.count // 5
//要素の列挙
for char in string {
print(char)
}
実行結果
a
b
c
d
e
string.count
は、Int型でstringの文字数の値を返します。
for char in string { }
は、stringの文字数分{ }内の処理を繰り返します。
今回は、"abcde"の5文字なので5回処理を繰り返します
またcharに入る値ですが、
1回目の処理はcharにstringの1文字目が、
2回目の処理はcharにstringの2文字目がと順に入っていきます。
(for文に関しては別記事に詳しく記載する予定です!)
普段使っている特に意識せず使っていたString型ですが、
いろいろな機能を備えていたんですね・・・。
まだまだ自分の知識は足らないなと思ったので、
もっと勉強に励まなければなと思いました。
以上。最後までご覧いただきありがとうございました!