Reputation: 119
I am in the middle of building an app and have run into something I can't quite solve. The gist of it is that I have a view that allows the user to turn off/on filters. I currently have these filters linked to an NSObject called Filter. The filter object has the following properties:
@property (nonatomic, strong) NSString *activity;
@property (nonatomic, strong) NSString *mileage;
@property (nonatomic, assign) BOOL pets;
@property (nonatomic, assign) BOOL accessibility;
@property (nonatomic, assign) BOOL fee;
Below is what the Filter view looks like:
Then I have Trail objects which contain the following properties:
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSMutableArray *activities;
@property (nonatomic, strong) NSString *miles;
@property (nonatomic, assign) BOOL pets;
@property (nonatomic, assign) BOOL accessibility;
@property (nonatomic, assign) BOOL fee;
What I am having problems with somehow creating a dynamic if statement so that if certain filters are turned on or not nil (say activity, pets, mileage) then a for loop would go through all of my trail objects and compare their properties to the selected filters. If the Trail objects' filters (in this example activity, pets and mileage) don't match the filter objects then they aren't added to the new array. So the issue I cant solve is creating an if statement that only includes the filters that have been turned on:
if( (selectedFilter1 == trailProperty1) && (selectedFilter2 == trailProperty2) etc...)
Upvotes: 0
Views: 117
Reputation: 3001
I think the problem is with your Filter
object. There's 2 things I can think of that you could do:
Add 5 more BOOL
s to keep track of if a filter should be applied. EDIT: see Merlevede's answer for details.
Change all the properties of your Filter
to NSString
s, and set the value to @"Deactivated"
or some other special string to track that it shouldn't be used. Then, in your for
loop, check to see if a given value is that "Deactivated" string. If it is not, then apply the filter on your Trail
object.
I can't really see a reason to choose one approach over the other - in fact I think I probably use both at some point or another in my project, depending on what mood I was in when I programmed that part. You can just pick whichever you are more comfortable with.
Upvotes: 1
Reputation: 41226
A sequence of:
if((!filterPetsOn || filterPets == trail.pets) &&
(!filterBikingOn || filterBiking == trail.biking) &&
...)
Should do what you're wanting.
Upvotes: 1
Reputation: 350
I worked on a project with a partner and we had a similar problem: searching through a list of colleges by their name, code, state, level, etc (And you had to be able to turn certain filters on or off) So there is a solution for your dynamic -if- but it's not that simple (or at least our solution wasn't, I hope it isn't the most confusing)
So this is the solution: Your Trailer class could have an array of Criteria (another class) and each Criteria would have the selected options, ie: Pets allowed: yes/no and its name (PetFilter) Afterwards your Trailers (which I suppose you have in a NSMutableArray, or similar) loops recursively though the Criteria array. The Critera is added depending if the user selected to use the filter or not. How does the looping work: if the filter is not nil then use the filter to compare all the trailers, if a trailer does not match the criteria it is removed from the array and continue to the next Criteria (if it is set) therefore leaving you with the results. Each criteria would use a determined compare method. I hope this gives you somewhat of an idea!
Upvotes: 1
Reputation: 7145
There is no way around not checking all 5 of your Filter object's properties on/off states (as represented by a UISwitch
) because at run time you don't know if none or all of the properties have been turned on by the user.
Upvotes: 1
Reputation: 8170
It would be best if you have 5 additional booleans where you have the state of your switches and have something like this
BOOL match = true;
if (filterOn1)
{
match &= (selectedFilter1 == trailProperty1);
}
if (filterOn2)
{
match &= (selectedFilter2 == trailProperty2);
}
...
I'm assuming trailPropertyX
is the value for the current item in your iteration loop
Upvotes: 2