0

I need to concatenate a string based on some logic but I cant figure out how to do it.

Example:

var filterString: String = ""
var hasFilter: Bool = false

    if let catId = param["catid"] {
        filterString += "cat_id=\(catId)"
        hasFilter = true
    }

    if let subCatId = param["subcatid"] {
        filterString += "sub_cat_id=\(subCatId)"
        hasFilter = true
    }

    if let locationId = param["stateid"] {
        filterString += "location_id=\(locationId)"
        hasFilter = true
    }


    if hasFilter == true {
        query.filters = filterString
    }

This will only work if I have ONE filter in my query

Eg: query.filters = "location_id=4"

But if I happend to have two or more filters my query will break eg:

query.filters = "location_id=4cat_id=3"

If I have more then one filter I need to seperate it with a AND statement like this:

query.filters = "location_id=4 AND cat_id=3"

But I cant figure out how to do it since I never know what order the filter will come in or if there even will be one or more filters to begin with

Edit

I seem to get it working by:

 var filterString: String = ""
    var hasFilter: Bool = false

        if let catId = param["catid"] {
            filterString += "cat_id=\(catId)"
            hasFilter = true
        }

        if let subCatId = param["subcatid"] {
            if hasFilter == true {
            filterString += " AND sub_cat_id=\(subCatId)"
             } else {
             filterString += "sub_cat_id=\(subCatId)"
            }
            hasFilter = true
        }

        if let locationId = param["stateid"] {
         if hasFilter == true {
         filterString += " AND location_id=\(locationId)"
         } else {
          filterString += "location_id=\(locationId)"
          }
            hasFilter = true
        }


        if hasFilter == true {
            query.filters = filterString
        }
user2636197
  • 3,982
  • 9
  • 48
  • 69
  • Is this for building a NSPredicate? In that case I strongly recommend to use NSCompoundPredicate and predicateWithFormat: instead of string manipulation. Here are some examples: http://stackoverflow.com/questions/39027558/how-to-combine-multiple-nullable-nspredicates, http://stackoverflow.com/questions/34202239/nspredicate-with-multiple-arguments-and-and-behaviour. – Martin R Oct 21 '16 at 14:29
  • @MartinR No I am using this: http://algolia.com/ – user2636197 Oct 21 '16 at 14:41
  • 2
    Please don't post your final solution as an edit to your question. If you have solved your own issue (even if it is not the best way to solve it), you should post it as an answer, not an edit to your question. – rmaddy Oct 21 '16 at 17:50

3 Answers3

2

One solution would be to put the filters into an array and then if the array isn't empty, combine the array values with an " AND " separator.

var filters : [String] = []
if let catId = param["catid"] {
    filters.append("cat_id=\(catId)")
}

if let subCatId = param["subcatid"] {
    filters.append("sub_cat_id=\(subCatId)")
}

if let locationId = param["stateid"] {
    filters.append("location_id=\(locationId)")
}

if filters.count > 0 {
    query.filters = filters.joined(separator: " AND ")
}
rmaddy
  • 314,917
  • 42
  • 532
  • 579
  • I seem to get it working now, I posted my updated code :) – user2636197 Oct 21 '16 at 17:46
  • 2
    Why do it the hard way? That's a lot of needless `if` statements and redundant code. – rmaddy Oct 21 '16 at 17:49
  • Oh sorry I didnt understand. ``query.filters`` must be equal to a string. And I thought that ``query.filters = filters.joined(separator: " AND ")`` would only make it a string if there was more than one item – user2636197 Oct 21 '16 at 22:04
  • No. `filters.joined` returns a `String` no matter how many are in the array. The `if` check just makes sure there is at least one. – rmaddy Oct 21 '16 at 22:06
  • Ah awesome! But how does it know when to add ``" AND "`` Does it do that if there are more than one element? – user2636197 Oct 21 '16 at 22:07
  • Yes, it will put `" AND" ` between each string. Of course if there is only one, it won't add it at all. You'll just get the one string. Try it. – rmaddy Oct 21 '16 at 22:08
  • Aha okey. I just read the docs saying **separator: A string to insert between each of the elements in this sequence. The default separator is an empty string.** Reading that I did not get that it would not add a seperator if only one string existed – user2636197 Oct 21 '16 at 22:16
0

Maybe you can first create an array and append all the filters. After that create another variable to append all the values in the array.

Abhishek Biswas
  • 1,125
  • 1
  • 13
  • 19
0

Another option using inline if statements:

    var param = ["catid" : "111", "subcatid" : "222", "stateid" : "333"]

    var filterString = ""

    if let catId = param["catid"] {
        filterString = "cat_id=\(catId)"
    }

    if let subCatId = param["subcatid"] {
        filterString.appendContentsOf(filterString.characters.count > 0 ? " AND sub_cat_id=\(subCatId)" : "sub_cat_id=\(subCatId)")
    }

    if let locationId = param["stateid"] {
        filterString.appendContentsOf(filterString.characters.count > 0 ? " AND location_id=\(locationId)" : "location_id=\(locationId)")
    }

    print(filterString)

    if (filterString.characters.count > 0) {
        query.filters = filterString
    }
random
  • 8,568
  • 12
  • 50
  • 85