Bruno
Bruno

Reputation: 1032

Filtering objects array with an inside array with another array

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.

Upvotes: 0

Views: 70

Answers (3)

Fabio Felici
Fabio Felici

Reputation: 2906

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 ?? []) }

Upvotes: 1

PGDev
PGDev

Reputation: 24341

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.

Upvotes: 1

rmaddy
rmaddy

Reputation: 318774

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 }

Upvotes: 1

Related Questions