Showing posts with label NSMutableIndexSet example. Show all posts
Showing posts with label NSMutableIndexSet example. Show all posts

Friday, June 21, 2013

NSMutableIndexSet removeIndexesInRange example in Objective C (iOS).


NSMutableIndexSet removeIndexesInRange

Removes the indexes in an index range from the receiver.

- (void)removeIndexesInRange:(NSRange)indexRange

Parameters of [NSMutableIndexSet removeIndexesInRange]
indexRange
Index range to remove.

NSMutableIndexSet removeIndexesInRange example.
You may want to look at NSMutableIndexSet. It is designed to efficiently store ranges of numbers.

You can initialize it like this:

NSMutableIndexSet *set = [[NSMutableIndexSet alloc]
    initWithIndexesInRange:NSMakeRange(1, 100000)];
Then you can remove, for example, 123 from it like this:

[set removeIndex:123];
Or you can remove 400 through 409 like this:

[set removeIndexesInRange:NSMakeRange(400, 10)];
You can iterate through all of the remaining indexes in the set like this:

[set enumerateIndexesUsingBlock:^(NSUInteger i, BOOL *stop) {
    NSLog(@"set still includes %lu", (unsigned long)i);
}];
or, more efficiently, like this:

[set enumerateRangesUsingBlock:^(NSRange range, BOOL *stop) {
    NSLog(@"set still includes %lu indexes starting at %lu",
        (unsigned long)range.length, (unsigned long)range.location);
}];

End of NSMutableIndexSet removeIndexesInRange example article.

NSMutableIndexSet removeIndexes example in Objective C (iOS).


NSMutableIndexSet removeIndexes

Removes the indexes in an index set from the receiver.

- (void)removeIndexes:(NSIndexSet *)indexSet

Parameters of [NSMutableIndexSet removeIndexes]
indexSet
Index set to remove.

NSMutableIndexSet removeIndexes example.
You may want to look at NSMutableIndexSet. It is designed to efficiently store ranges of numbers.

You can initialize it like this:

NSMutableIndexSet *set = [[NSMutableIndexSet alloc]
    initWithIndexesInRange:NSMakeRange(1, 100000)];
Then you can remove, for example, 123 from it like this:

[set removeIndex:123];
Or you can remove 400 through 409 like this:

[set removeIndexesInRange:NSMakeRange(400, 10)];
You can iterate through all of the remaining indexes in the set like this:

[set enumerateIndexesUsingBlock:^(NSUInteger i, BOOL *stop) {
    NSLog(@"set still includes %lu", (unsigned long)i);
}];
or, more efficiently, like this:

[set enumerateRangesUsingBlock:^(NSRange range, BOOL *stop) {
    NSLog(@"set still includes %lu indexes starting at %lu",
        (unsigned long)range.length, (unsigned long)range.location);
}];

End of NSMutableIndexSet removeIndexes example article.

NSMutableIndexSet removeIndex example in Objective C (iOS).


NSMutableIndexSet removeIndex

Removes an index from the receiver.

- (void)removeIndex:(NSUInteger)index

Parameters of [NSMutableIndexSet removeIndex]
index
Index to remove.

NSMutableIndexSet removeIndex example.
You may want to look at NSMutableIndexSet. It is designed to efficiently store ranges of numbers.

You can initialize it like this:

NSMutableIndexSet *set = [[NSMutableIndexSet alloc]
    initWithIndexesInRange:NSMakeRange(1, 100000)];
Then you can remove, for example, 123 from it like this:

[set removeIndex:123];
Or you can remove 400 through 409 like this:

[set removeIndexesInRange:NSMakeRange(400, 10)];
You can iterate through all of the remaining indexes in the set like this:

[set enumerateIndexesUsingBlock:^(NSUInteger i, BOOL *stop) {
    NSLog(@"set still includes %lu", (unsigned long)i);
}];
or, more efficiently, like this:

[set enumerateRangesUsingBlock:^(NSRange range, BOOL *stop) {
    NSLog(@"set still includes %lu indexes starting at %lu",
        (unsigned long)range.length, (unsigned long)range.location);
}];

Example of [NSMutableIndexSet removeIndex].
- (NSUInteger)indexForImageGivenIndexSet:(NSIndexSet*)indexSet             // Set of indexes you want to select from
                         prizeImageIndex:(NSUInteger)prizeIndex      // The prize index
                        probabilityScale:(CGFloat)probabilityScale   // The scale for the prize (8.0 for 8x less than the others)
{
    // If invalid, return what was given
    if (![indexSet containsIndex:prizeIndex]) {
        return prizeIndex;
    }

    // Calculate our probabilities
    // For a set of 4, with a scale of 8 on the prize, our probabilities would be
    // 0.04 (prize), 0.32, 0.32, 0.32
    double prizeProbability = (1.0 / indexSet.count) * (1.0 / probabilityScale);

    double val = (double)arc4random() / RAND_MAX;

    if (val < prizeProbability) {
        return prizeIndex;
    }
    else {
        // Select from the others in range equally
        NSMutableIndexSet* newSet = [[NSMutableIndexSet alloc] initWithIndexSet:indexSet];
        [newSet removeIndex:prizeIndex];

        NSInteger selectedPosition = arc4random() % newSet.count;
        __block NSInteger count = 0;
        return [newSet indexPassingTest:^BOOL(NSUInteger idx, BOOL *stop) {
            if (count == selectedPosition) {
                *stop = YES;
                return YES;
            }
            else {
                count++;
                return NO;
            }
        }];
    }
}

NSMutableIndexSet removeIndex example.
You will have to make subclass of the NSTableView class. This is basic example how you could do it. It handles selection with the spacebar and with the right mouse button, hoever it does not handle right mouse button drag selection.

The idea is to use NSTableView in single select mode and implement alternative selection. We add property markedRows and then use it instead of original selectedRows property.

FOTableView.h

#import <Cocoa/Cocoa.h>

@interface FOTableView : NSTableView

@property (strong,nonatomic) NSMutableIndexSet *markedRows;

@end
FOTableView.m

#import "FOTableView.h"

@implementation FOTableView

- (id)initWithFrame:(NSRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
    }

    return self;
}

-(NSMutableIndexSet *) markedRows
{
    if (!_markedRows) {
        _markedRows = [NSMutableIndexSet new];
    }
    return _markedRows;
}

- (void)drawRow:(NSInteger)row clipRect:(NSRect)clipRect
{
    if ([self.markedRows containsIndex:row]) {
        NSRect clipRect = [self rectOfRow:row];
        NSColor *color =  [NSColor colorWithCalibratedRed:0.932 green:0.046 blue:0.960 alpha:1.000];
        [color setFill];
        NSRectFill(clipRect);
    }

    [super drawRow:row clipRect:clipRect];
}

- (void)keyDown:(NSEvent *)theEvent
{
    NSString *keyString;
    unichar  keyChar;

    keyString = [theEvent charactersIgnoringModifiers];
    keyChar = [keyString characterAtIndex:0];
    NSInteger row = [self selectedRow];
    switch(keyChar){           
        case 32:
        {
             if (row != -1)
             {
                 if ([self.markedRows containsIndex:row]) {
                     [self.markedRows removeIndex:row];
                 }
                 else {
                     [self.markedRows addIndex:row];
                 }
             }
            [self selectRowIndexes:[NSIndexSet indexSetWithIndex:++row] byExtendingSelection:NO];
            [self setNeedsDisplay:YES];
            break;
        }

        default:
            [super keyDown:theEvent];
    }

    NSLog(@"key pressed: (%hu)%@", keyChar,keyString);
}

- (void)rightMouseDown:(NSEvent *)theEvent
{
    NSInteger row = [self rowAtPoint:[self convertPoint:[theEvent locationInWindow] fromView:nil]];
    if ([self.markedRows containsIndex:row]) {
        [self.markedRows removeIndex:row];
    }
    else {
        [self.markedRows addIndex:row];
    }

    [self setNeedsDisplay:YES];
}

@end

End of NSMutableIndexSet removeIndex example article.

NSMutableIndexSet removeAllIndexes example in Objective C (iOS).


NSMutableIndexSet removeAllIndexes

Removes the receiver’s indexes.

- (void)removeAllIndexes

NSMutableIndexSet removeAllIndexes example.
#import "NumberCreator.h"

@implementation NumberCreator
@synthesize levels, numbers;

- (id)init
{
    if ( !(self = [super init] ) )
        return nil;

    numbers = [NSMutableIndexSet new];
    return self;
}

- (void)create
{
    [numbers removeAllIndexes];
    [numbers addIndex:1];

    NSMutableIndexSet *nextLevel = [NSMutableIndexSet indexSet];
    NSMutableIndexSet *currentLevel = [NSMutableIndexSet indexSetWithIndex:1];

    for (int i = 0; i < levels; i++ )
    {
        [currentLevel enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {

            if ( ! [numbers containsIndex:idx * 2] )
                [nextLevel addIndex:idx * 2];

            if ( idx % 6 == 4 && ! [numbers containsIndex:(idx - 1) / 3] )
                [nextLevel addIndex:(idx - 1) / 3];
        }];

        [numbers addIndexes:nextLevel];
        [currentLevel removeAllIndexes];
        [currentLevel addIndexes:nextLevel];
        [nextLevel removeAllIndexes];
    }

    [numbers enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
        NSLog(@"%i", idx);
    }];
}

@end

Example of [NSMutableIndexSet removeAllIndexes].
//Not tested
//Assume that selectedIndexes is a NSMutableIndexSet
if ([selectedIndexes containsIndex:indexPath.row]) {
    if (self.options.count) {//This could probably be optimised depend on your goal
        [selectedIndexes addIndexesInRange:NSMakeRange(0,self.options.count-1)];
    } else {
        [selectedIndexes removeAllIndexes];
    }
} 

NSMutableIndexSet removeAllIndexes example.
- (void)createFilteredTableGroups{

    //Checking for the usual suspects. all which may through an exception
    if(model==nil)
        return;
    if(tableGroups==nil)
        return;
    if([tableGroups count]==0)
        return;

    //lets make a new array to work with
    NSMutableArray *newTableGroups = [[allTableGroups mutableCopy] autorelease];

    //telling the table what we are about to do
    [self.tableView beginUpdates];

    //array to track cells for deletion animation
    NSMutableArray *indexesToRemove = [NSMutableArray array];

    //loop through each section
    for(NSMutableArray *eachSection in tableGroups){

        //keeping track of the indexes to delete for each section
        NSMutableIndexSet *indexesForSection = [NSMutableIndexSet indexSet];
        [indexesForSection removeAllIndexes];

        //increment though cell indexes
        int rowIndex = 0;

        //loop through each cellController in the section
        for(ScheduleCellController *eachCellController in eachSection){

            //Ah ha! A little magic. the cell controller must know if it should be displayed.
            //This you must calculate in your business logic
            if(![eachCellController shouldDisplay]){

                //add non-displayed cell indexes
                [indexesForSection addIndex:rowIndex];

            }
            rowIndex++;  
        }
        //adding each array of section indexes, EVEN if it is empty (no indexes to delete)
        [indexesToRemove addObject:indexesForSection];

    }

    //Now we remove cell controllers in newTableGroups and cells from the table
    //Also, each subarray of newTableGroups is mutable as well
    if([indexesToRemove count]>0){

        int sectionIndex = 0;
        for(NSMutableIndexSet *eachSectionIndexes in indexesToRemove){

            //Now you know why we stuck the indexes into individual arrays, easy array method
            [[newTableGroups objectAtIndex:sectionIndex] removeObjectsAtIndexes:eachSectionIndexes];

            //tracking which cell indexPaths to remove for each section
            NSMutableArray *indexPathsToRemove = [NSMutableArray array];
            int numberOfIndexes = [eachSectionIndexes count];

            //create array of indexPaths to remove
            NSUInteger index = [eachSectionIndexes firstIndex];
            for(int i = 0; i< numberOfIndexes; i++){

                NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index inSection:sectionIndex];
                [indexPathsToRemove addObject:indexPath];
                index = [eachSectionIndexes indexGreaterThanIndex:index];
            }

            //delete the rows for this section
            [self.tableView deleteRowsAtIndexPaths:indexPathsToRemove withRowAnimation:UITableViewRowAnimationTop];

            //next section please
            sectionIndex++;
        }

    }

    //now we figure out if we need to remove any sections
    NSMutableIndexSet *sectionsToRemove = [NSMutableIndexSet indexSet];
    [sectionsToRemove removeAllIndexes];

    int sectionsIndex = 0;
    for(NSArray *eachSection in newTableGroups){

        //checking for empty sections
        if([eachSection count]==0)
            [sectionsToRemove addIndex:sectionsIndex];

        sectionsIndex++;
    }

    //updating the table groups
    [newTableGroups removeObjectsAtIndexes:sectionsToRemove];

    //removing the empty sections
    [self.tableView deleteSections:sectionsToRemove withRowAnimation:UITableViewRowAnimationTop];

    //updating filteredTableGroups to the newTableGroups we just created
    self.filteredTableGroups = newTableGroups;

    //pointing tableGroups at the filteredGroups
    tableGroups = filteredTableGroups;

    //invokes the animation
    [self.tableView endUpdates];

}

End of NSMutableIndexSet removeAllIndexes example article.

NSMutableIndexSet addIndexesInRange example in Objective C (iOS).


NSMutableIndexSet addIndexesInRange

Adds the indexes in an index range to the receiver.

- (void)addIndexesInRange:(NSRange)indexRange

Parameters
indexRange
Index range to add. Must include only indexes representable as unsigned integers.

Discussion of [NSMutableIndexSet addIndexesInRange]
This method raises an NSRangeException when indexRange would add an index that exceeds the maximum allowed value for unsigned integers.

NSMutableIndexSet addIndexesInRange example.
//Not tested
//Assume that selectedIndexes is a NSMutableIndexSet
if ([selectedIndexes containsIndex:indexPath.row]) {
    if (self.options.count) {//This could probably be optimised depend on your goal
        [selectedIndexes addIndexesInRange:NSMakeRange(0,self.options.count-1)];
    } else {
        [selectedIndexes removeAllIndexes];
    }
} 

Example of [NSMutableIndexSet addIndexesInRange].
@autoreleasepool {
      
        // insert code here...
        NSLog(@"Hello, World!");
        NSRange indexRange = NSMakeRange(0, 6);
        NSMutableIndexSet *newIndexSet = [[NSMutableIndexSet alloc] initWithIndexesInRange:indexRange];
        for (int i=0; i<40; i++)
        {
            NSUInteger x = [newIndexSet oneTimeRandomIndex];
            if (x == NSNotFound)
            {
                                       // NSLog(@"newIndexSet needs to be refilled");
                [newIndexSet addIndexesInRange:indexRange];
                x = [newIndexSet oneTimeRandomIndex];
              
            }
            switch (x) {
                case 0:
                    NSLog(@"Cat");
                    break;
                case 1:
                    NSLog(@"Dog");
                    break;
                case 2:
                    NSLog(@"Fish");
                    break;
                case 3:
                    NSLog(@"Horse");
                    break;
                case 4:
                    NSLog(@"Bird");
                    break;
                case 5:
                    NSLog(@"Wombat");
                    break;  
                default:
                    break;
            }
          
        }

         NSLog(@"See Ya Later, World!");
    }
    return 0;

End of NSMutableIndexSet addIndexesInRange example article.

NSMutableIndexSet addIndexes example in Objective C (iOS).


NSMutableIndexSet addIndexes

Adds the indexes in an index set to the receiver.

- (void)addIndexes:(NSIndexSet *)indexSet

Parameters of [NSMutableIndexSet addIndexes]
indexSet
Index set to add.

NSMutableIndexSet addIndexes example.
Because, you work only with integer, using a NSMutableIndexSet would be much more efficient.

#import "NumberCreator.h"

@implementation NumberCreator
@synthesize levels, numbers;

- (id)init
{
    if ( !(self = [super init] ) )
        return nil;

    numbers = [NSMutableIndexSet new];
    return self;
}

- (void)create
{
    [numbers removeAllIndexes];
    [numbers addIndex:1];

    NSMutableIndexSet *nextLevel = [NSMutableIndexSet indexSet];
    NSMutableIndexSet *currentLevel = [NSMutableIndexSet indexSetWithIndex:1];

    for (int i = 0; i < levels; i++ )
    {
        [currentLevel enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {

            if ( ! [numbers containsIndex:idx * 2] )
                [nextLevel addIndex:idx * 2];

            if ( idx % 6 == 4 && ! [numbers containsIndex:(idx - 1) / 3] )
                [nextLevel addIndex:(idx - 1) / 3];
        }];

        [numbers addIndexes:nextLevel];
        [currentLevel removeAllIndexes];
        [currentLevel addIndexes:nextLevel];
        [nextLevel removeAllIndexes];
    }

    [numbers enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
        NSLog(@"%i", idx);
    }];
}

@end

Example of [NSMutableIndexSet addIndexes].
Have you tried this:

 [someIndexSet addIndexes:otherIndexSet]

NSMutableIndexSet addIndexes example.
RKObjectManager *manager = [RKObjectManager sharedManager];
    RKObjectMapping *map = [RKObjectMapping mappingForClass:[DataError class]];
    RKObjectMapping *sub =  [RKObjectMapping mappingForClass:[DataErrorDetail class]];
    [sub addAttributeMappingsFromDictionary: @{
     @"key": @"code",
     @"value": @"description",
     }];
    [map addAttributeMappingsFromDictionary: @{
     @"error": @"error",
     @"message": @"message"
     }];
   
    [map addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"reasons" toKeyPath:@"reasons" withMapping:sub]];
   
    NSMutableIndexSet *codes = [[NSMutableIndexSet alloc] init];
    [codes addIndexes:RKStatusCodeIndexSetForClass(RKStatusCodeClassClientError)];
    [codes addIndexes:RKStatusCodeIndexSetForClass(RKStatusCodeClassServerError)];
   
    [manager addResponseDescriptor:
     [RKResponseDescriptor responseDescriptorWithMapping:map pathPattern:nil keyPath:@"error" statusCodes:codes]];

End of NSMutableIndexSet addIndexes example article.

NSMutableIndexSet addIndex example in Objective C (iOS).


NSMutableIndexSet addIndex

Adds an index to the receiver.

- (void)addIndex:(NSUInteger)index

Parameters of [NSMutableIndexSet addIndex]
index
Index to add.

NSMutableIndexSet addIndex example.
If the indexes are consecutive like in your example, you can use this:

NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(1, 3)];
If not, create a mutable index set and add the indexes (or ranges) one by one:

NSMutableIndexSet *indexSet = [NSMutableIndexSet indexSet];
[indexSet addIndex:3];
[indexSet addIndex:5];
[indexSet addIndex:8];

Example of [NSMutableIndexSet addIndex].
Keep track as you add values to the index set:

NSMutableIndexSet *set = [NSMutableIndexSet indexSet];
NSUInteger maxIndexs = 0;
NSUInteger indexOfMax = NSNotFound;
for (NSString *subCat in results) {
    NSUInteger indexs = 0;
    for (NSString *comp in components) {
        if ([subCat rangeOfString:comp].location != NSNotFound) {
            indexs ++;
        }
    }

    if (indexes > maxIndexs) {
        maxIndexs = indexs;
        indexOfMax = set.count;
    }
    [set addIndex:indexs];
}

// find the position of the highest amount of matches in the index set
NSUInteger highestIndex = indexOfMax;

returns = [results objectAtIndex:highestIndex];

NSMutableIndexSet addIndex example.
You can not enumerate and modify the NSMutableIndexSet you are enumerating. Just create a new NSMutableIndexSet and add the entries to it. It is doubtful that there is a performance hit.

Example (with ARC):

NSMutableIndexSet *originalIndexSet = [NSMutableIndexSet new];
[originalIndexSet addIndex:1];
[originalIndexSet addIndex:5];

NSMutableIndexSet *newIndexSet = [NSMutableIndexSet new];
[originalIndexSet enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
    [newIndexSet addIndex:idx+1];
}];

NSLog(@"originalIndexSet: %@", originalIndexSet);
NSLog(@"newIndexSet:      %@", newIndexSet);
Then

originalIndexSet = newIndexSet;
NSLog output:

originalIndexSet: [number of indexes: 2 (in 2 ranges), indexes: (1 5)]
newIndexSet: [number of indexes: 2 (in 2 ranges), indexes: (2 6)]

End of NSMutableIndexSet addIndex example article.