2016-06-15 5 views
0

Ok, also sagen wir, ich habe ein benutzerdefiniertes Objekt für Vokabeln, alternative Schreibweise und ihre Bedeutung.Finden Sie Übereinstimmung in Array für gegebene Zeichenfolge?

class VocabEntry { 
    var kanji:String? 
    var kana:String? 
    var meaning:String? 
} 

Dann habe ich ein Array, bestehend aus diesen Objekten. Hier ist zum Beispiel ein.

let newVocabWord = VocabEntry() 
newVocabWord.kanji = "下さい” 
newVocabWord.kana = "ください” 
newVocabWord.meaning = "please" 

Jetzt habe ich einen Text-String:

let testString = "すみません、十階のボタンを押して下さい" 

Wie kann ich diese Zeichenfolge meiner Reihe von benutzerdefinierten Objekten zu vergleichen, und verweisen auf die Ergebnisse (die Strings enthalten)?

Ich versuchte es.

if vocabArray.contains({ $0.kanji == testString }) { 
    print("yes") 
} 

Aber das versucht, die gesamte Zeichenfolge übereinstimmen. Wenn ich testString zu "下 さ い" ändere, funktioniert es, aber das ist nicht das, wonach ich suche. Was ich will ist, dass es sagt "Hier habe ich い さ い in xx Objekt gefunden. Hier ist die Indexnummer."

Antwort

1

Sie können indexOf() mit einem Prädikat verwenden, um den Index eines übereinstimmenden Eintrags und containsString() nach Teilzeichenfolgen zu suchen. Da die kanji Eigenschaft optional ist, müssen Sie das optional über überprüfen Bindung:

if let index = vocabArray.indexOf({ entry in 
    if let kanji = entry.kanji { 
     // check if `testString` contains `kanji`: 
     return testString.containsString(kanji) 
    } else { 
     // `entry.kanji` is `nil`: no match 
     return false 
    } 
}) { 
    print("Found at index:", index) 
} else { 
    print("Not found") 
} 

Diese knappe mehr geschrieben werden kann als

if let index = vocabArray.indexOf({ 
    $0.kanji.flatMap { testString.containsString($0) } ?? false 
}) { 
    print("Found at index:", index) 
} else { 
    print("Not found") 
} 

Um die Indizes der alle passende Einträge zu erhalten, das folgende würde funktionieren:

let matchingIndices = vocabArray.enumerate().filter { (idx, entry) in 
    // filter matching entries 
    entry.kanji.flatMap { testString.containsString($0) } ?? false 
}.map { 
    // reduce to index 
    (idx, entry) in idx 
} 
print("Found at indices:", matchingIndices) 
+0

Funktioniert wie ein Charme! Vielen Dank. –

+0

Eigentlich funktioniert das aber nur für ein einziges Spiel. In Wirklichkeit hat mein vocabArray etwa 1400 Einträge. Für eine gegebene Eingabe-Zeichenkette sollte es um des Arguments willen Übereinstimmungen bei den Indizes 3, 252, 563, 1304, usw. geben. Aber dies hört auf, nachdem es die erste gefunden hat. Wie würden Sie fortfahren, indem Sie für jedes gefundene Match Indizes zu einem Array hinzufügen? –

+0

@JosephToronto: Ich habe eine mögliche Lösung hinzugefügt. –

Verwandte Themen