Swiftで文字列の部分文字列はどのように機能しますか?質問する

Swiftで文字列の部分文字列はどのように機能しますか?質問する

私は古いコードと回答の一部を Swift 3 で更新していましたが、Swift 文字列とサブ文字列によるインデックス作成に至ったときに混乱が生じました。

具体的には、次のことを試していました。

let str = "Hello, playground"
let prefixRange = str.startIndex..<str.startIndex.advancedBy(5)
let prefix = str.substringWithRange(prefixRange)

2行目に次のエラーが表示されました

'String' 型の値にはメンバー 'substringWithRange' がありません

String現在、次のメソッドがあることがわかりました。

str.substring(to: String.Index)
str.substring(from: String.Index)
str.substring(with: Range<String.Index>)

最初は本当に混乱したので、いろいろ試してみましたインデックスと範囲これは、substring に関するフォローアップの質問と回答です。使用方法を示すために、以下に回答を追加します。

ベストアンサー1

ここに画像の説明を入力してください

以下の例はすべて

var str = "Hello, playground"

スイフト4

Swift 4 では、文字列が大幅に改良されました。文字列から部分文字列を取得すると、Substringではなく 型が返されますString。これはなぜでしょうか? Swift では、文字列は値型です。つまり、1 つの文字列を使用して新しい文字列を作成する場合、その文字列をコピーする必要があります。これは安定性には良いことですが (知らないうちに他の誰かが変更することはありません)、効率性には悪影響です。

一方、サブ文字列は、元の文字列への参照です。これは、ドキュメンテーションそれを例証します。

コピーする必要がないため、はるかに効率的に使用できます。ただし、100 万文字の文字列から 10 文字の部分文字列を取得したとします。部分文字列は文字列を参照しているため、システムは部分文字列が存在する限り文字列全体を保持する必要があります。したがって、部分文字列の操作が完了したら、必ず文字列に変換してください。

let myString = String(mySubstring)

これにより、部分文字列のみがコピーされ、古い文字列を保持しているメモリは再生された部分文字列 (型として) は、短命であることが想定されています。

Swift 4 のもう 1 つの大きな改善点は、文字列がコレクションになったことです (再び)。つまり、コレクションに対して実行できることはすべて、文字列に対しても実行できます (添え字の使用、文字の反復処理、フィルター処理など)。

次の例は、Swift で部分文字列を取得する方法を示しています。

部分文字列の取得

文字列から部分文字列を取得するには、添え字やその他の方法 (たとえば、、、) を使用しますprefix。ただし、範囲のインデックスではなく、を使用する必要があります。(suffixsplitString.IndexInt私の他の答えご支援が必要な場合にはご連絡ください。

文字列の先頭

下付き文字を使用できます (Swift 4 の片側範囲に注意してください)。

let index = str.index(str.startIndex, offsetBy: 5)
let mySubstring = str[..<index] // Hello

またはprefix

let index = str.index(str.startIndex, offsetBy: 5)
let mySubstring = str.prefix(upTo: index) // Hello

あるいはもっと簡単です:

let mySubstring = str.prefix(5) // Hello

文字列の終了

下付き文字の使用:

let index = str.index(str.endIndex, offsetBy: -10)
let mySubstring = str[index...] // playground

またはsuffix

let index = str.index(str.endIndex, offsetBy: -10)
let mySubstring = str.suffix(from: index) // playground

あるいはもっと簡単です:

let mySubstring = str.suffix(10) // playground

suffix(from: index)を使用する場合、 を使用して末尾から逆算する必要があることに注意してください。 を使用する場合は、文字列の最後の文字だけを取得する-10ため、その必要はありません。suffix(x)x

文字列内の範囲

ここでも、単に下付き文字を使用します。

let start = str.index(str.startIndex, offsetBy: 7)
let end = str.index(str.endIndex, offsetBy: -6)
let range = start..<end

let mySubstring = str[range]  // play

変換SubstringするString

忘れないでください。部分文字列を保存する準備ができたら、String古い文字列のメモリをクリーンアップできるように、それを に変換する必要があります。

let myString = String(mySubstring)

インデックス拡張機能を使用していますIntか?

Intこの記事を読んだ後、ベースインデックス拡張機能の使用をためらっていますSwift 3 の文字列Airspeed Velocity と Ole Begemann による。Swift 4 では文字列はコレクションですが、Swift チームは意図的にIntインデックスを使用していません。それでもなおString.Index、これは Swift 文字がさまざまな数の Unicode コードポイントで構成されていることに関係しています。実際のインデックスは、文字列ごとに一意に計算する必要があります。

Swift チームが将来的に抽象化の方法を見つけてくれることを期待していますString.Index。しかし、それまでは、私は彼らの API を使うことにします。文字列操作が単なるインデックス検索ではないことを思い出すのに役立ちますInt

おすすめ記事