0

This is more of a logic question. I wanted to see different approaches. I am trying to create a filter array based on multiple criteria. Let's say I have 4 boolean criteria, I will set these with a simple toggle button.

   NSObject* A; BOOL booleanA TRUE;
   NSObject* B;BOOL booleanB FALSE;
   NSObject* C;BOOL booleanC TRUE;
   NSObject* D;BOOL booleanD FALSE;

What I want to achieve is to end up with an array with objects with TRUE boolean values like :

NSArray: {A, C}

I was going to use the most straightforward approach:

if(booleanA)[array addObject:A];
if(booleanB)[array addObject:B];
if(booleanC)[array addObject:C];
if(booleanD)[array addObject:D];

Looks fine to me, but maybe you can come up with something different and simpler. I literally cant think of any other way.

2 Answers2

1

You look for an algorithmic solution. Right now, you manually transform 4 (unrelated, albeit similar named) BOOLs into 1 array. You can only write an algorithm when there's a 1:1 match, instead of a N:1 transformation. So I suggest you try to put booleanA to booleanD in a container instead of fiddling around with seemingly unrelated variables.

If you put the booleans into an array with fixed positions, using consts or macros for the indexes (booleans[B_INDEX]), you can write an algorithm to transform the truthiness at index i into letter A+i, so to speak.

If you use a small collection class instead, you can even get rid of handling arrays and matching indexes.

I would prefer a collection class so that the other class using this stuff doesn't get too bloated. The four lines you show look similar, but since the BOOLs have nothing in common but their name, you won't be able to write an algorithm yet. Encapsulating an algorithm like @user3571918 proposed will hide the matching from your calling class. Also, it hides the fact that 4 lines of manual transformation may have turned into a 30+ lines value object or service class :)

Will using a more complex, algorithmic solution pay off? I think this is the case if you plan on adding more switches later so you don't have to change the calling class just because its data representation was extended.

Example code

Here's an example algo I'd put into a utility class to hide the fact that the number of elements is fixed from other classes.

NSArray *booleans = @[@0, @1, @0, @1]; // array representation 
NSArray *transformations = @[@"A", @"B", @"C", @"D"];  // matching utility
NSMutableArray *result = [NSMutableArray array];

[booleans savedArray enumerateObjectsUsingBlock:^(NSNumber *boolean, NSUInteger idx, BOOL *stop) {
    BOOL isToggled = [boolean booleanValue];
    id transformation = transformations[idx];

    if (isToggled)
    {
        [result addObject:transformation];
    }
}];

// result will be:  @[@"B", @"D"];

How you assemble booleans depends on the code you already have. Maybe handing the toggle switches over as a variadic argument list to a utility method works, maybe it will be simpler.

ctietze
  • 2,805
  • 25
  • 46
0

The issue is that a Boolean operator is not an object. You might be better off utilizing @0 and @1 for your purposes, and no matter what you'd have to objectify your Boolean value to place in NSArray. The workaround for that is to utilize a C array, however, since you asked for a more convenient way to derive your answer utilizing Objective-C, I'll stick with that.

Basically, I think your question boils down to 'how to enumerate NSArray' and there are some options. Here's a good high level resource regarding NSArray. There are other ways to do it, and especially flexible with enumerateWithBlock as described here previously.

With fast enumeration you can have code that may look similar to the following:

NSArray* array = @[@0, @1, @0, @1];

for (NSNumber* number in array) {
    if ([number isEqualToNumber:@0]) {
        // action here
        return;
    }

    // else action here
}
Community
  • 1
  • 1
aug2uag
  • 3,379
  • 3
  • 32
  • 53