1

I am trying to setup a dictionary to have a string key with a numeric value (that needs to be incremented.

This is how I am initializing with value 1.

[person.list setObject:[NSNumber numberWithInteger:1] forKey:name];

How would I go about incrementing the value as needed?

Undo
  • 25,519
  • 37
  • 106
  • 129
john cs
  • 2,220
  • 5
  • 32
  • 50

6 Answers6

8

Get the object from the dictionary for the key, do the modification and then add that object to the dictionary for same key, this will replace previous object.

NSInteger number = [[dict objectForKey:name] integerValue];
number+=1;

[dict setObject:[NSNumber numberWithInteger:number] forKey:name];
Prasad Devadiga
  • 2,573
  • 20
  • 43
1

Use a sweet-ass category,

@interface NSNumber (NSNumber_Incrementing)    
-(NSNumber *)increment;    
@end

@implementation NSNumber (NSNumber_Incrementing)    
-(NSNumber *)increment {
     return [NSNumber numberWithInt:[self intValue] + 1];
}


[person.list setObject:[mynumb increment] forKey:name];

that means you need to hold mynumb

Add a protocol for NSDecimal et al.

@protocol Incrementing
- (NSNumber *)increment;
@end
so the above might be
@interface NSNumber (NSNumber_Incrementing) <Incrementing>
...
@interface NSDecimableNumber (NSNumber_Incrementing) <Incrementing>

But even f*ng sweeter is a category on Dictionary:

@interface NSDictionary (NSDictionary_SweetIncrementing) 
    -(void) incrementNumberForKey:name;  
@end

@implementation NSDictionary (NSDictionary_SweetIncrementing) 
-(void) incrementNumberForKey:name throws NSNumberException {
         NSNumber numb = (NSNumber *)[self valueForKey: name];         
         return [self setValue: [numb increment] forKey: name];
}
@end

valueForKey and setValue belong to NSDictionary. You are using a NSMutableDictionary that offers objectForKey and setObject.... so do that instead if so desired.

Yeah. And add some exceptions for key not associated with number

A similar question

Community
  • 1
  • 1
Gabe Rainbow
  • 3,658
  • 4
  • 32
  • 42
  • `increment` makes it sound like the `NSNumber` itself is changing, which is impossible because it's not mutable. I'd change the method name to something else. – StilesCrisis Apr 30 '13 at 05:27
  • Hi I'm trying to use the category on dictionary though I'm, getting this error. **Expected ':'** on the line -> throws NSNumberException. I ended up just deleting throws NSNumberException and it works great. Really nice way to make helpers in Objective C. Just curious but why place this in the category -> (NSDictionary_SweetIncrementing)? – uplearned.com Jun 05 '20 at 06:42
0

If its sequential increment than a static integer will be helpful!

static int increment = 1;

[person.list setObject:[NSNumber numberWithInteger:increment++] forKey:name];

If you're unaware of static variables, this question can be helpful.

Community
  • 1
  • 1
Hemang
  • 26,840
  • 19
  • 119
  • 186
0

Not really sure what you are trying to achieve, but one solution could be

[person.list setObject:[NSNumber numberWithInteger:person.list.count+1] forKey:name];
Erik
  • 5,791
  • 5
  • 30
  • 45
  • I don't need to know the current numbers of entries in the dictionary, my goal is to retrieve the current integer that is the value and increment it by 1. – john cs Apr 30 '13 at 04:48
  • @johnhannigan And what prevents you from that, seriously? –  Apr 30 '13 at 04:51
  • @johnhannigan **Are you serious?** I've been developing for iOS for 3 years. I know `NSDictionary` can hold Objective-C objects only, but this is so trivial I had a hard time understanding what your problem was at all. –  Apr 30 '13 at 05:02
0
    NSNumber *num = [person.list objectForKey:name];
    if(!num) [person.list setObject:[NSNumber numberWithInteger:1] forKey:name];
    else [person.list setObject:[NSNumber numberWithInteger:([num intValue]+1)] forKey:name];
Thilina Chamath Hewagama
  • 9,039
  • 3
  • 32
  • 45
0

First, make sure person.list is an instance of NSMutableDictionary. (Also might want to change the list property on person to a different name. List implies an Array-like structure rather than a Dictionary.)

You can use the new NSDictionary syntax and the primitive to object boxing. I'm assuming the number is an unsigned integer here.

person.list[name] = @([person.list[name] unsignedIntegerValue] + 1);

That is syntactically similar to (split into multiple lines for readability)

NSUInteger previous = [[person.list objectForKey:name] unsignedIntegerValue];
NSNumber *incremented = [NSNumber numberWithUnsignedInteger:previous + 1];
[person.list setObject:incremented forKey:name];

The @(...) syntax converts a primitive number to an NSNumber object. While the [name] syntax is shorthand for setObject:forKey: of NSMutableDictionary.

Jason Harwig
  • 43,743
  • 5
  • 43
  • 44