3

I have a model named Item and Tag. Item has multi tags. I need to filter array of items by another array of tags. Tags to be used for filter are given by array of string.

I googled but couldn't find answer to solve my situation.

struct Tag {
    let id: Int
    let name: String
}

struct Item {
    let id: Int
    let tags: [Tag]
}

func filter(items: [Item], contains tags: [String]) -> [Item] {
    // Need to implement filter
}

0

1 Answer 1

3

Chose 1 in 2 option of return:

     func filter(items: [Item], contains tags: [String]) -> [Item] {
        items.filter { (item) -> Bool in
            let tagNames = item.tags.map({ $0.name })
            return tags.allSatisfy(tagNames.contains)
            return Set(tags).isSubset(of: Set(tagNames))
        }
    }
Sign up to request clarification or add additional context in comments.

6 Comments

The map is wasteful. You can just do: tags.allSatisfy { tag in item.tags.contains(tag) }
@Alexander the tags is [String], but item.tags is [Tag]
so then: tags.allSatisfy { tag in item.tags.contains(where: { $0.name == tag.name } }
@Alexander Thank you, but it should be: tags.allSatisfy { tag in item.tags.contains(where: { $0.name == tag })}. And if writing like this i think the onwner of this question will hard to understand
Yeah, I would extract that predicate into a named function like hasTag, so it could read like tags.allSatisfy(item.hasTag)
|

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.