0

Ok so lets say I have an custom object for vocabulary words, alternate way of being written, and their meaning.

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

Then I have an array comprised of these objects. Here's one for example.

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

Now I have a string of text:

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

How can I compare that string to my array of custom objects (that contain strings) and reference the matches?

I tried.

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

But that trying to match the entire string. If I change testString to "下さい" it works, but that's not what I'm looking for. What I want is for it to say "Here I found 下さい in xx object. Here's the index number."

1 Answer 1

1

You can use indexOf() with a predicate to find the index of a matching entry, and containsString() to search for substrings. Since the kanji property is optional, you have to check that via optional binding:

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")
}

This can be written more concise as

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

To get the indices of all matching entries, the following would work:

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)
Sign up to request clarification or add additional context in comments.

4 Comments

Works like a charm! Thank you.
Actually this works but only for a single match. In reality my vocabArray has about 1400 entries. For a given input string there should for argument's sake be a matches at indexes 3, 252, 563, 1304, etc.. But this stops after it finds the first one. How would you have it continue, adding indexes to an array for each match found?
@JosephToronto: I have added a possible solution.
That seems to do the trick. It's going to take me a while to figure out how exactly this works though. Thank you.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.