0

How do I create Filter variable or Multiple filters in swift? such as :

let i2 = $0.bCondition == "nonac"
let i3 = $0.aCondition == "nonac"
let i4 = $0.cCondition == "nonac"
if <some condition>{
  let i5 = $0.vCondition == "nonac"
  let i6 = $0.mCondition == "nonac"
 }
final filter = i2+i3+i4+i6+i5

This is what I'm looking for, is there any solutions are available? please guide me through a proper solution.

5
  • aCondition, bCondition, etc. seem like quite a code smell. You could probably make those into a Dictionary, making filtering quite trivial Commented Jun 20, 2016 at 12:20
  • can you show me a code example? Commented Jun 20, 2016 at 12:26
  • Not really, because I don't know enough about the nature of the problem you're trying to solve Commented Jun 20, 2016 at 12:34
  • I want to add multiple filters but dynamically. This is the problem. Commented Jun 20, 2016 at 12:50
  • 1
    That doesn't tell me much about the aCondition and other fields, what they do, and whether or not they can be reworked into a dictionary Commented Jun 20, 2016 at 12:55

2 Answers 2

3

From the way it looks you want not simply dynamically add filters but also dynamically evaluate them. For this purpose you could use closures and some operators declared to operate on them:

// Closure that takes no arguments and returns Bool
typealias Filter = () -> Bool

// Convenience operator to combine outputs of two filters with AND operator
func && (lhs: Filter, rhs: Filter) -> Filter {
    return {
        lhs() && rhs()
    }
}

// Convenience operator to combine outputs of two filters with OR operator
func || (lhs: Filter, rhs: Filter) -> Filter {
    return {
        lhs() || rhs()
    }
}

Example:

var foo = "Foo"
let bar = "Bar"
let qux = "Qux"

let filter1: Filter = { foo == "Foo" }
let filter2: Filter = { bar == "Bar" }
let filter3: Filter = { qux == "Qux" }
let compositeFilter = filter1 && filter2 && filter3
//                  ^-- Is this what you are looking for?

let before = compositeFilter()

foo = "FOO"

let after = compositeFilter()

print(before)   // true
print(after)    // false
Sign up to request clarification or add additional context in comments.

1 Comment

This is the way I'm looking for, A composite dynamic filter
0

One way to do this is to convert your aCondition, bCondition, etc. fields into a Dictionary. From there, you can get the keys from your dictionary, and do some simple set arithmetic:

struct Struct {
    let dict : [String : String]
}

let struct1 = Struct(dict: [
    "aCondition" : "a",
    "bCondition" : "b",
    "cCondition" : "c"
])

let struct2 = Struct(dict: [
    "aCondition" : "a",
    "bCondition" : "b",
    "cCondition" : "nonac"
])

let structs = [struct1, struct2] //structs to be filtered

let filters : Set = ["cCondition"] //the keys to be checked for "nonac"

let filtered = structs.filter{ //filter all structs
    let dict = $0.dict //get the dict of keys from the current iteration
    let keys = Set(dict.keys) //make a set from the dict keys
    let keysToCheck = keys.intersection(filters) //filter out to get the keys we want

    let values = keysToCheck.map{dict[$0]} //get the values for the keys to check

    return values.contains{$0 != "nonac"} //only keep if value != "nonac"
}

print(filtered)print(output)

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.