I am trying to create a filtering system for some items by checking if the selected items exist in the presented values.
So my selectable array can range from 0
to 6
, and each item contains an array of Ints that it is associated with:
let items = [
Item(cat: [1, 2, 3]),
Item(cat: [0, 6]),
Item(cat: []),
Item(cat: [0, 1])
]
I wanted to create a function that would check if any of the cat
values were in the selected Ints:
@Published var filteredCats: [Int] = []
func filterByInt(array: [Item]) -> [Item] {
let output = array.filter({
guard let cats = $0.cats else { return true }
for cat in cats {
return filteredCats.contains(cat)
}
})
return output
}
But I'm having issue with the above since it returns
in the loop on the first iteration, so if I was searching for 1
in the above items
then Item(cat: [0, 1])
exits at false as the first looped check is 0==1
.
Essentially I want to be able to do the following (in expanded terms):
let filter = [0, 3, 4]
let items = [
[1, 2, 3],
[2, 3],
[],
[5, 6, 7]
]
items.contains(filter) // --> return the arrays
Sorry if this is basic but I've been trying to find a good solution.
CodePudding user response:
Checking uniqueness is where a Set can help
struct Item {
var cat: Set<Int>
}
let items = [
Item(cat: [1, 2, 3]),
Item(cat: [0, 6]),
Item(cat: []),
Item(cat: [0, 1])
]
let wanted: Set<Int> = [0, 3, 4]
let filtered = items.filter { !$0.cat.isDisjoint(with: wanted) }
CodePudding user response:
I'd suggest someSatisfy
(or any
in Kotlin):
We can utilize allSatisfy
with double negations (one for allSatisfy
, the other for contains
) for that:
struct Item: CustomDebugStringConvertible {
let cat: [Int]
var debugDescription: String {
"[" cat.map { String($0) }.joined(separator: ", ") "]"
}
}
func filterByInt(items: [Item], filter: [Int]) -> [Item] {
// Early return might make sense if the filter is empty.
// guard !filter.isEmpty else { return items }
items.filter { item in
!filter.allSatisfy {
filterItem in !item.cat.contains(filterItem)
}
}
}
let filter = [0, 3, 4]
let items: [Item] = [
.init(cat: [1, 2, 3]),
.init(cat: [2, 3]),
.init(cat: []),
.init(cat: [5, 6, 7])
]
print(filterByInt(items: items, filter: filter))
// [[1, 2, 3], [2, 3]]
print(filterByInt(items: items, filter: [5]))
// [[5, 6, 7]]
print(filterByInt(items: items, filter: []))
// []