[解決済み] SwiftでString.Indexはどのように動作するのか
質問
私はSwift 3で古いコードと答えを更新してきましたが、Swiftの文字列とインデックスに到達すると、物事を理解するのに苦労しています。
具体的には以下のようなことを試していました。
let str = "Hello, playground"
let prefixRange = str.startIndex..<str.startIndex.advancedBy(5) // error
ここで、2行目が次のようなエラーになっていました。
'advancedBy' は使用できません。インデックスを n ステップ進めるには、インデックスを生成した CharacterView インスタンスに対して 'index(_:offsetBy:)' を呼び出してください。
なるほど
String
には、以下のメソッドがあります。
str.index(after: String.Index)
str.index(before: String.Index)
str.index(String.Index, offsetBy: String.IndexDistance)
str.index(String.Index, offsetBy: String.IndexDistance, limitedBy: String.Index)
最初は本当に混乱したので、理解できるまで遊びました。これらがどのように使用されるかを示すために、以下に答えを追加しています。
解決方法は?
以下の例では、すべて
var str = "Hello, playground"
startIndex
と
endIndex
-
startIndex
は最初の文字のインデックス -
endIndex
はインデックス 後 最後の文字
例
// character
str[str.startIndex] // H
str[str.endIndex] // error: after last character
// range
let range = str.startIndex..<str.endIndex
str[range] // "Hello, playground"
Swift 4の 片側範囲 であれば,以下のいずれかの形式に簡略化することができる.
let range = str.startIndex...
let range = ..<str.endIndex
以下の例では、わかりやすくするために完全な形を使いますが、読みやすくするために、おそらくあなたのコードでは片側だけの範囲を使いたいと思うことでしょう。
after
のように。
index(after: String.Index)
-
after
は、指定されたインデックスの直後の文字のインデックスを参照します。
例
// character
let index = str.index(after: str.startIndex)
str[index] // "e"
// range
let range = str.index(after: str.startIndex)..<str.endIndex
str[range] // "ello, playground"
before
のように。
index(before: String.Index)
-
before
は、指定されたインデックスの直前の文字のインデックスを参照します。
例
// character
let index = str.index(before: str.endIndex)
str[index] // d
// range
let range = str.startIndex..<str.index(before: str.endIndex)
str[range] // Hello, playgroun
offsetBy
のように。
index(String.Index, offsetBy: String.IndexDistance)
-
は
offsetBy
の値は正でも負でもよく、与えられたインデックスから始まる。この型はString.IndexDistance
を与えることができます。Int
.
例
// character
let index = str.index(str.startIndex, offsetBy: 7)
str[index] // p
// range
let start = str.index(str.startIndex, offsetBy: 7)
let end = str.index(str.endIndex, offsetBy: -6)
let range = start..<end
str[range] // play
limitedBy
のように。
index(String.Index, offsetBy: String.IndexDistance, limitedBy: String.Index)
-
は
limitedBy
は、オフセットによってインデックスが境界外に出ないことを確認するのに便利です。これは、バウンディングインデックスです。オフセットが制限を超える可能性があるため、このメソッドは Optional を返します。を返します。nil
は、インデックスが境界外である場合
例
// character
if let index = str.index(str.startIndex, offsetBy: 7, limitedBy: str.endIndex) {
str[index] // p
}
もしオフセットが
77
ではなく
7
の場合、その後に
if
文はスキップされたはずです。
なぜString.Indexが必要なのですか?
それは
大いに
を使用する方が簡単です。
Int
を文字列のインデックスとして使用します。を新たに作成しなければならないのは
String.Index
は、Swift の文字がすべて同じ長さではないことです。Swift の単一の文字は、1つ、2つ、あるいはそれ以上の Unicode コードポイントから構成されるかもしれません。したがって、それぞれのユニークな文字列は、その文字のインデックスを計算する必要があります。
この複雑さをIntインデックスの拡張で隠すことは可能ですが、私はそれをしたくありません。実際に何が起こっているのかを思い知らされるのは良いことです。
関連
-
[解決済み] Swift 3でdispatch_onceはどうなる?
-
[解決済み] JavaScriptで文字列が部分文字列を含むかどうかを確認する方法は?
-
[解決済み] JavaでInputStreamを読み込んでStringに変換するにはどうすればよいですか?
-
[解決済み] Pythonには文字列の'contains'サブストリングメソッドがありますか?
-
[解決済み] JavaでStringをintに変換するにはどうしたらいいですか?
-
[解決済み] 文字列の単語を反復処理するにはどうすればよいですか?
-
[解決済み] リストの最後の要素を取得する方法
-
[解決済み] SwiftでStringのサブストリングはどのように動作するか
-
[解決済み】JavaScriptで文字列の出現箇所をすべて置換する方法
-
[解決済み】==と===の違いについて
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Swiftの辞書にキーが含まれているかどうかを判断し、その値を取得する。
-
[解決済み] Swift - 呼出しの余分な引数
-
[解決済み] Fatal error.とは何ですか?Unexpectedly found nil while unwrapping an Optional value" とはどういう意味ですか?
-
[解決済み] SwiftでString.Indexはどのように動作するのか
-
[解決済み] Swiftで#pragmaマーク?
-
[解決済み] Swift: print() vs println() vs NSLog()
-
[解決済み] SwiftでStringのサブストリングはどのように動作するか
-
[解決済み] テキストファイルからの文字列の読み込みと書き込み
-
[解決済み】Swiftのオプション値とは何ですか?
-
[解決済み] Swiftで範囲を作成する方法は?