2016-08-31 25 views
9

Chcę pobrać losowy emoji w zakresie.Uzyskaj wartość w indeksie z zakresu

let emojiRanges = [ 
        0x1F601...0x1F64F, 
        0x1F680...0x1F6C0, 
       ] 
       let flattenEmoji = emojiRanges.flatten() 
// the loop for emoji works 
       for i in flattenEmoji { 

        let st = String(format:"0x%2X %@", i, String(UnicodeScalar(i))) 
        print(st) 
       } 

// but this is not possible to obtain value at wanted index 
//there is a compiler error: 
       let randomSign = String(UnicodeScalar(flattenEmoji[arc4random_uniform(UInt32(flattenEmoji.count))])) 
       print("RANDOM \(randomSign)") 

błąd:

ViewController.swift:68:67: Cannot subscript a value of type 'FlattenBidirectionalCollection<[Range]>' (aka 'FlattenBidirectionalCollection>>') with an index of type 'UInt32'

Co to jest właściwy sposób, aby uzyskać wynik?

Odpowiedz

8

Problemem jest to, że flatten() leniwie jest stosowane, a w związku z tym zwraca się szczególną FlattenBidirectionalCollection, który jest indeksowany przez FlattenBidirectionalCollectionIndex raczej niż Int.

Najprostszym rozwiązaniem byłoby zatem, aby po prostu użyć konstruktora Array(_:) (lub flatMap(_:)) w celu chętnie stosują spłaszczenie zakresach, które będą tworzyć tablicę, które można następnie indeks z Int.

let flattenEmoji = Array(emojiRanges.flatten()) // In Swift 3, flatten() is named joined() 

let randomIndex = Int(arc4random_uniform(UInt32(flattenEmoji.count))) 
let randomSign = String(UnicodeScalar(flattenEmoji[randomIndex])) 

Jeśli chcesz zachować spłaszczenie czym leniwie stosowane, można indeks ten FlattenBidirectionalCollection bezpośrednio (dla Swift 2) poprzez zastosowanie advancedBy(_:) na zbieranie na startIndex:

let randomIndex = flattenEmoji.startIndex.advancedBy(Int(arc4random_uniform(UInt32(flattenEmoji.count)))) 
let randomSign = String(UnicodeScalar(flattenEmoji[randomIndex])) 

w Swift 3 , jako collections move their indices, zamiast tego należy użyć metody kolekcji: index(_:offsetBy:):

let randomIndex = flattenEmoji.index(flattenEmoji.startIndex, offsetBy: Int(arc4random_uniform(UInt32(flattenEmoji.count)))) 
4

Zmień emojiRanges deklaracja do tego:

let emojiRanges = Array(0x1F601...0x1F64F) + Array(0x1F680...0x1F6C0) 

wtedy życie stanie się o wiele łatwiejsze.

for i in emojiRanges { 
    let st = String(format:"0x%2X %@", i, String(UnicodeScalar(i))) 
    print(st) 
} 

w randomSign należy przekonwertować indeks Int

let randomSign = String(UnicodeScalar(emojiRanges[Int(arc4random_uniform(UInt32(emojiRanges.count)))])) 
print("RANDOM \(randomSign)") 
Powiązane problemy