web-dev-qa-db-ja.com

Swift 3.0 String.Index範囲で反復

Swift 2.2:

let m = "alpha"
for i in m.startIndex..<m.endIndex {
    print(m[i])
}
a
l
p
h
a

3.0では、次のエラーが発生します。

タイプ「Range」(別名「Range」)はプロトコル「Sequence」に準拠していません

Swift-文字列の前半を単純にトラバースする(またはより一般的な問題:文字列の範囲をトラバースする))の文字列を使用して、非常に簡単な操作をしようとしています。

私は次のことができます:

let s = "string"
var midIndex = s.index(s.startIndex, offsetBy: s.characters.count/2)
let r = Range(s.startIndex..<midIndex)
print(s[r])

しかし、ここでは文字列を実際に走査していません。質問は次のとおりです。指定された文字列の範囲をどのように横断するか。好む:

for i in Range(s.startIndex..<s.midIndex) {
    print(s[i])
}
25
p0lAris

次のようにindicesプロパティのcharactersプロパティを使用して、文字列を走査できます。

let letters = "string"
let middle = letters.index(letters.startIndex, offsetBy: letters.characters.count / 2)

for index in letters.characters.indices {

    // to traverse to half the length of string 
    if index == middle { break }  // s, t, r

    print(letters[index])  // s, t, r, i, n, g
}

セクションの documentation文字列と文字-文字のカウントから:

拡張された書記素クラスタは、1つ以上のUnicodeスカラーで構成できます。これは、異なる文字(および同じ文字の異なる表現)が格納するために異なるメモリ量を必要とする可能性があることを意味します。このため、Swiftの文字は、それぞれ文字列表現内で同じ量のメモリを消費しません。その結果、aの文字数はstringは、stringを反復処理して拡張された書記素クラスタ境界を決定しないと計算できません。

強調は私自身のものです。

これは機能しません:

let secondChar = letters[1] 
// error: subscript is unavailable, cannot subscript String with an Int
27
Khundragpan

別のオプションはenumerated()を使用することです:例:

let string = "Hello World"    
for (index, char) in string.characters.enumerated() {
    print(char)
}

またはfor Swift 4だけを使用

let string = "Hello World"    
for (index, char) in string.enumerated() {
    print(char)
}
19
Andrew

以下を使用してください。

for i in s.characters.indices[s.startIndex..<s.endIndex] {
  print(s[i])
}

Migrating to Swift 2.3 or Swift 3 from Swift 2.2

7
Dmitry

Swift 4:

let myString = "Hello World"    
for char in myString {
    print(char)
}
6
djruss70

Stringの文字をトラバースしたい場合は、Stringのインデックスに明示的にアクセスする代わりに、単にCharacterViewString を使用して作業できます。 CollectionType を使用すると、prefix(_:)などの適切なサブシーケンスメソッドにアクセスできます。

_/* traverse the characters of your string instance,
   up to middle character of the string, where "middle"
   will be rounded down for strings of an odd amount of
   characters (e.g. 5 characters -> travers through 2)  */
let m = "alpha"
for ch in m.characters.prefix(m.characters.count/2) {
    print(ch, ch.dynamicType)
} /* a Character
     l Character */

/* round odd division up instead */
for ch in m.characters.prefix((m.characters.count+1)/2) {
    print(ch, ch.dynamicType)
} /* a Character
     l Character 
     p Character */
_

ループ内の文字を文字列として扱いたい場合は、上記のString(ch)を使用してください。


以下のコメントに関して:CharacterViewの範囲にアクセスしたい場合は、CollectionTypeの独自の拡張を簡単に実装できます(_Generator.Element_がCharacterの場合に指定されます)prefix(_:)およびsuffix(_:)は、たとえば次のサブコレクションを生成します半開き(_from..<to_)範囲

_/* for values to >= count, prefixed CharacterView will be suffixed until its end */
extension CollectionType where Generator.Element == Character {
    func inHalfOpenRange(from: Int, to: Int) -> Self {
        guard case let to = min(to, underestimateCount()) where from <= to else {
            return self.prefix(0) as! Self
        }
        return self.prefix(to).suffix(to-from) as! Self
    }
}

/* example */
let m = "0123456789"    
for ch in m.characters.inHalfOpenRange(4, to: 8) {
    print(ch)         /*  \                                   */
} /* 4                     a (sub-collection) CharacterView
     5
     6
     7 */
_
3
dfri

これを行う最良の方法は次のとおりです。

 let name = "nick" // The String which we want to print.

  for i in 0..<name.count 
{
   // Operation name[i] is not allowed in Swift, an alternative is
   let index = name.index[name.startIndex, offsetBy: i]
   print(name[index])
}

詳細については、 こちら をご覧ください

1
Nikhil Patil

Swift 4.2

単に:

let m = "alpha"
for i in m.indices {
   print(m[i])
}
0

スウィフト4:

let mi: String = "hello how are you?"
for i in mi {
   print(i)
}
0
Saif

Swift 4の文字列の範囲をトラバースする方法を具体的に示すために、whereループでforフィルターを使用して、その実行を指定された範囲:

_func iterateStringByRange(_ sentence: String, from: Int, to: Int) {

    let startIndex = sentence.index(sentence.startIndex, offsetBy: from)
    let endIndex = sentence.index(sentence.startIndex, offsetBy: to)

    for position in sentence.indices where (position >= startIndex && position < endIndex) {
        let char = sentence[position]
        print(char)
    }

}
_

iterateStringByRange("string", from: 1, to: 3)trおよびiを出力します

0
teacup