0

Let's use the following code example to elaborate on my question:

struct exampleObj {
    var str: String?
    var arr: [String]?
}

let filterArray = ["something1", "ins1", "something2"]

let obj1 = exampleObj(str: "obj1", arr: ["ins2", "ins3"])
let obj2 = exampleObj(str: "obj2", arr: ["ins1", "ins2"])
let obj3 = exampleObj(str: "obj3", arr: ["ins1", "ins4"])
let obj4 = exampleObj(str: "obj4", arr: ["ins3", "ins4"])

var arrayObj = [obj1, obj2, obj3, obj4]

let result = arrayObj.filter { filterArray.contains($0.arr...)} //??? I get lost here, dunno if right approach.

What I'm trying to do is to filter arrayObj by using another array filterArray, resulting on a result with only objects of type exampleObj containing ins1.

I hope I was clear. Any doubt about the question, I'm here.

1
  • Whats the purpose of declaring your properties optional if they will never be nil? struct ExampleObj { let str: String let arr: [String] } btw it is Swift naming convention to name your structures starting with an UppercaseLetter Commented Jun 13, 2019 at 16:45

3 Answers 3

1

You need to find matches where there is an intersection between values of the two arrays. This is more easily done with sets. You also need to deal with arr being optional.

let result = arrayObj.filter { !Set(filterArray).intersection($0.arr ?? []).isEmpty }

This would be more efficient if you declare filterArray as a Set to begin with.

let filterSet: Set = ["something1", "ins1", "something2"]

let obj1 = exampleObj(str: "obj1", arr: ["ins2", "ins3"])
let obj2 = exampleObj(str: "obj2", arr: ["ins1", "ins2"])
let obj3 = exampleObj(str: "obj3", arr: ["ins1", "ins4"])
let obj4 = exampleObj(str: "obj4", arr: ["ins3", "ins4"])

var arrayObj = [obj1, obj2, obj3, obj4]

let result = arrayObj.filter { !filterSet.intersection($0.arr ?? []).isEmpty }
Sign up to request clarification or add additional context in comments.

Comments

1

You can simply do by finding non-empty intersection between filterArray and exampleObj's arr, i.e.

let filterSet = Set(filterArray)
let result = arrayObj.filter { (exampleObj) -> Bool in
    if let arr = exampleObj.arr {
        return !filterSet.intersection(arr).isEmpty
    }
    return false
}

Output: result contains obj1 and obj2.

Comments

1

Try this:

let result = arrayObj.filter { obj in
    filterArray.contains { filter in
        obj.arr?.contains(filter) ?? false
    }
}

or using Set:

let result = arrayObj.filter { !Set(filterArray).isDisjoint(with: $0.arr ?? []) }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.