[解決済み】Swift Stringで文字のインデックスを検索する
質問
そろそろ負けを認めてもいいのでは...。
Objective-Cでは、こんなのが使えました。
NSString* str = @"abcdefghi";
[str rangeOfString:@"c"].location; // 2
Swiftでは、似たようなものがありますね。
var str = "abcdefghi"
str.rangeOfString("c").startIndex
...しかし、これでは
String.Index
これは、元の文字列に添字で戻すには使えますが、位置を取り出すには使えません。
ちなみに、その
String.Index
というプライベートなivarを持っています。
_position
には正しい値が入っています。ただ、それがどのように公開されているのかがわからないのです。
自分で簡単にStringに追加できるのは分かっています。それよりも、この新しいAPIで何が欠けているのかが気になります。
どのように解決するのですか?
解決策が見つからないのは、あなただけではありません。
String
は実装されていません。
RandomAccessIndexType
. おそらく、異なるバイト長の文字を有効にするためでしょう。そのため、私たちは
string.characters.count
(
count
または
countElements
Swift 1.xでは) を使って文字数を取得します。それはポジションにも当てはまります。そのため
_position
は、おそらくバイトの生の配列へのインデックスであり、それを公開したくないのでしょう。そのため
String.Index
は、文字の途中のバイトにアクセスするのを防ぐためのものです。
つまり、取得するインデックスは必ず
String.startIndex
または
String.endIndex
(
String.Index
実装
BidirectionalIndexType
). その他のインデックスを作成するには
successor
または
predecessor
メソッドを使用します。
さて、インデックスを助けるために、メソッド(Swift 1.xでは関数)の集合があります。
スイフト4.x
let text = "abc"
let index2 = text.index(text.startIndex, offsetBy: 2) //will call succ 2 times
let lastChar: Character = text[index2] //now we can index!
let characterIndex2 = text.index(text.startIndex, offsetBy: 2)
let lastChar2 = text[characterIndex2] //will do the same as above
let range: Range<String.Index> = text.range(of: "b")!
let index: Int = text.distance(from: text.startIndex, to: range.lowerBound)
Swift 3.0
let text = "abc"
let index2 = text.index(text.startIndex, offsetBy: 2) //will call succ 2 times
let lastChar: Character = text[index2] //now we can index!
let characterIndex2 = text.characters.index(text.characters.startIndex, offsetBy: 2)
let lastChar2 = text.characters[characterIndex2] //will do the same as above
let range: Range<String.Index> = text.range(of: "b")!
let index: Int = text.distance(from: text.startIndex, to: range.lowerBound)
Swift 2.x
let text = "abc"
let index2 = text.startIndex.advancedBy(2) //will call succ 2 times
let lastChar: Character = text[index2] //now we can index!
let lastChar2 = text.characters[index2] //will do the same as above
let range: Range<String.Index> = text.rangeOfString("b")!
let index: Int = text.startIndex.distanceTo(range.startIndex) //will call successor/predecessor several times until the indices match
Swift 1.x
let text = "abc"
let index2 = advance(text.startIndex, 2) //will call succ 2 times
let lastChar: Character = text[index2] //now we can index!
let range = text.rangeOfString("b")
let index: Int = distance(text.startIndex, range.startIndex) //will call succ/pred several times
との連携
String.Index
は面倒ですが、ラッパーを使用して整数でインデックスを作成します (
https://stackoverflow.com/a/25152652/669586
) は、本当のインデックスの非効率性を隠してしまうので、危険です。
なお、Swiftのインデックス実装には ある文字列のために作成されたインデックス/レンジは、別の文字列に確実に使用することはできません。 といった具合です。
Swift 2.x
let text: String = "abc"
let text2: String = "????????????"
let range = text.rangeOfString("b")!
//can randomly return a bad substring or throw an exception
let substring: String = text2[range]
//the correct solution
let intIndex: Int = text.startIndex.distanceTo(range.startIndex)
let startIndex2 = text2.startIndex.advancedBy(intIndex)
let range2 = startIndex2...startIndex2
let substring: String = text2[range2]
Swift 1.x
let text: String = "abc"
let text2: String = "????????????"
let range = text.rangeOfString("b")
//can randomly return nil or a bad substring
let substring: String = text2[range]
//the correct solution
let intIndex: Int = distance(text.startIndex, range.startIndex)
let startIndex2 = advance(text2.startIndex, intIndex)
let range2 = startIndex2...startIndex2
let substring: String = text2[range2]
関連
-
[解決済み] 一見、空のファイルや文字列がmd5sumを生成するのはなぜですか?
-
[解決済み] JavaScriptで文字列が部分文字列を含むかどうかを確認する方法は?
-
[解決済み] C#のStringとstringの違いは何ですか?
-
[解決済み] JavaでInputStreamを読み込んでStringに変換するにはどうすればよいですか?
-
[解決済み] なぜパスワードにはStringではなくchar[]が好まれるのですか?
-
[解決済み] Pythonには文字列の'contains'サブストリングメソッドがありますか?
-
[解決済み] 文字列の単語を反復処理するにはどうすればよいですか?
-
[解決済み] バイトを文字列に変換する
-
[解決済み】JavaScriptで文字列の出現箇所をすべて置換する方法
-
[解決済み】大文字・小文字を区別しない「Contains(string)
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] strposではなく、単語が見つかったときのStataフラグ
-
[解決済み] PowerShellで文字列からテキストを削除する
-
[解決済み] PowerShell の " (" - 中括弧 ) の分割について
-
[解決済み】Java7で文字列からパスを作成する。
-
[解決済み】Scala:文字列のイテラブルを結合する
-
[解決済み】文字列から最後の文字を削除する。Swift言語
-
[解決済み】Swift - 文字列を複数行に分割する
-
[解決済み】String.substringWithRangeはどのように使うのですか?(または、SwiftでRangeはどのように動作しますか?)
-
[解決済み】「改行」と「キャリッジリターン」の違いは?
-
[解決済み】複数行の文字列リテラルの構文とは何ですか?