4

How can i filter an array of custom objects by one ore more flags ?

let flags = ["New product", "Season 2014", "Season 2015", "Product available"]

With one flag or more static flags is easy:

let filteredArray = myCustomObjectsArray.filter() { $0.isNew == true }

let filteredArray = myCustomObjectsArray.filter() { $0.isNew == true && $0.season.rangeOfString("14") && $0.season.rangeOfString("15") && $0.isAvailable }

But what if flags are dynamic i.e. flags array is created by user tapping on cells of the tableview ?

Other problem is an error when trying to concatenate multiple conditions in `filter() { condition1 && condition2 etc.}. " Expression was to complex to be solved in reasonable time ...".

So, flags array is what user selected (just titles from a tableview cells). If flags array is ["New product", "Season 2015"], i want to filter by .isNew and .season.rangeOfString("15") for example. So i'm sorting by properties and NOT by string.

Al Ex
  • 45
  • 1
  • 7
  • try this link [Filtering Arrays Containing Multiple Data Types in Swift](http://rshelby.com/2014/09/filtering-arrays-containing-multiple-data-types-in-swift/). – Hamza Ansari Aug 05 '15 at 06:40
  • You should really provide code that more accurately represents your problem, it is quite difficult to fully understand what you are trying to accomplish here. It would appear to be that you need to use the `flags` array in order to filter the `myCustomObjectsArray` array. Currently we can only assume **how** you want to filter, are you trying to use the strings in the `flags` array to filter based on the object's `season` using `rangeOfString`? Or is it something else? Please be more specific. – Steve Wilford Aug 05 '15 at 07:12
  • ok. i posted some examples to represent what i want but it might be unclear. sorry for that. so.. flags array is what user selected (just titles from a tableview cells). If flags array is ["New product", "Season 2015"], i want to filter by .isNew and .season.rangeOfString("15") for example. So sorting by properties and NOT by string. – Al Ex Aug 05 '15 at 07:29

3 Answers3

4

You have not posted all of the necessary code, where does .isNew and .season come from? It would appear to be custom objects.

The error you refer to ("Expression was too complex to be solved in reasonable time") already has an answer:

If condition failing with expression too complex

Having said that, you should be able to resolve this by separating out each part of the expression into separate statements:

let filteredArray = myCustomObjectsArray.filter() {
    let isNew = $0.isNew == true
    let is14 = $0.season.rangeOfString("14")
    let is15 = $0.season.rangeOfString("15")
    let isAvailable = $0.isAvailable
    return isNew && is14 && is15 && isAvailable
}
Community
  • 1
  • 1
Steve Wilford
  • 8,894
  • 5
  • 42
  • 66
  • like i said, i have an array of custom objects. each object has properties like 'isNew', 'season' etc. – Al Ex Aug 05 '15 at 07:07
0

For multiple condition try the following code. It might be helpful to you.

let tryAnchoredFirst = array1.filter { (text) -> Bool in
            let tmp: NSString = text

            var range = tmp.rangeOfString(searchText, options: NSStringCompareOptions.CaseInsensitiveSearch )
            return range.location != NSNotFound
        }
        // If the result of the filter is zero for first case then it will go to else part
        if tryAnchoredFirst.count > 0 {
            self.filteredTableData = tryAnchoredFirst
        }
        else {

            // Check second array
            self.filteredTableData = array2.filter { (text) -> Bool in

                let tmp: NSString = text
                var range = tmp.rangeOfString(searchText, options: NSStringCompareOptions.CaseInsensitiveSearch)
                return range.location != NSNotFound
            }
        }
Karlos
  • 1,653
  • 18
  • 36
0

Your Array is :

var flags = ["New product", "Season 2014", "Season 2015", "Product available"]

First of All you declare filteredArray

var filteredArray : [String] = [String]()

Make one Method rangeString to Check String is Available or Not.

func rangeString(x : String) -> [String]
    {
        if x.rangeOfString("Season") != nil {

            filteredArray += [x]
        }
        return filteredArray
    }

Now Calling the function as below

flags.map({x in self.rangeString(x)})

Print yout filteredArray and got result.

 println(filteredArray)

enter image description here

Note : Apply same idea for two string checking in array.

Filter array

Kirit Modi
  • 23,155
  • 15
  • 89
  • 112
  • well, i'm not trying to sort flags array. flags array are actually all selected filters to use in filter() method. so, filtered array is [CustomObject](). – Al Ex Aug 05 '15 at 07:05