Search code examples
arraysjsonswiftdictionarycontains

Swift - JSON Decode into Struct Contains Against String


I have a JSON file I am grabbing from a remote server and decoding it. It is being decoded into a struct and then used in an @Published var.

For example:

JSON:

[{"keyword": "foo"}, {"keyword": "blah"}]

Struct:

struct keywords: Codable {
var keyword: String
}

Observable Class:

@Published var keys: [keywords] = []

I need to do a real-time comparison, using contains, against a value the user is entering, utilizing an if statement. I can get it to use the first entry in the keys var and check against any characters that might be in that string, but I cannot get it to work across the entire array on only the full strings (not individual characters).

Here's what correctly checks against only the first entry of the array and each individual character.

if keys[0].keyword.contains(where: blah.contains)

I have also tried mapping it to strings like this (does exactly the same thing):

if (keys[0].keyword.map{String($0)}).contains(where: blah.contains)

Been at this all day but cannot find any docs on how to do this correctly.

The goal is to not just have it use the first entry of the array but the entirety of the entries of the array. I understand that is the [0] but it wouldn't compile without it. I need to make it compare on the entire string, not on individual characters.

For example, if the word blah is the array and the user enters bla it should not match anything. Only if the entire word blah is contained in the user's entry should it match (i.e. fooblahfoo would match because blah is within the string, but foobalbabh would NOT match even though all of the characters contained within the word blah are in that string).

Appreciate any assistance with actual code examples. This is Swift 5.5.

UPDATE:

Not sure where the confusion is coming from but here's an even clear explanation.

There is a TextField called username where the user enters a string.

If the user enters the string fooblahfoo and the word blah is somewhere in the array it should match.

This is easy when you have a simple array of strings like this: keywords = ["foo", "blah"]

For that you just do keywords.contains(where: username.contains)

However, the decoded JSON is more of a dictionary than a simple array of strings, so you have to call to the key of keyword and look at all the values in order to make the comparison.


Solution

  • First, use contains(where:) on the keys array -- then, check each item to see if the user input contains that keyword.

    struct Keywords: Codable {
        var keyword: String
    }
    
    var keys: [Keywords] = [.init(keyword: "foo"),.init(keyword: "blah")]
    var userInput = "fooblahfoo"
    var result = keys.contains { userInput.contains($0.keyword) }
    
    print(result)
    

    true