views:

229

answers:

3

I thought it would be simpler to find if an object in on a dictionary, but it appears it is not.

I have a NSMutableDictionary with just one key named "products".

I have several products added to the dictionary dynamically, using something like

[myDict addObject:@"banana" forKey:@"products"];
[myDict addObject:@"orange" forKey:@"products"];
[myDict addObject:@"grapes" forKey:@"products"];

etc.

At some point I would like to know if, for example, banana is on the dictionary.

Is there a way to do that? I mean, just to know if an object is on the dictionary?

thanks for any help.

+7  A: 

You're misunderstanding how dictionaries work. Dictionaries store a single value for a single key. So after your code runs, myDict will hold a single key-value pair: @"products" => @"grapes". If you need a key to point to multiple objects, then your key will need to point to an NSMutableArray (or NSMutableSet if you don't care about order), and then you add and remove things from the NSMutableArray rather than from the dictionary.

If this is going to be the basic structure for everything in your dictionary, you might want to consider making a wrapper for your dictionary, like so:

//DDMutableMultiValueDictionary.h
@interface DDMutableMultiValueDictionary : NSObject {
  NSMutableDictionary * dict;
}

- (void) addObject:(id)value forKey:(id)key;
- (void) removeObject:(id)value forKey:(id)key;
- (BOOL) containsObject:(id)value forKey:(id)key;

@end

//DDMutableMultiValueDictionary.m
#import "DDMutableMultiValueDictionary.h"

@implementation DDMutableMultiValueDictionary

- (id) init {
  if (self = [super init]) {
    dict = [[NSMutableDictionary alloc] init];
  }
  return self;
}

- (void) dealloc {
  [dict release];
  [super dealloc];
}

- (void) addObject:(id)value forKey:(id)key {
  NSMutableArray * values = [dict objectForKey:key];
  if (values == nil) {
    values = [NSMutableArray array];
    [dict setObject:values forKey:key]
  }
  [values addObject:value];
}

- (void) removeObject:(id)value forKey:(id)key {
  NSMutableArray * values = [dict objectForKey:key];
  [values removeObject:value];
}

- (BOOL) containsObject:(id)value forKey:(id)key {
  NSMutableArray * values = [dict objectForKey:key];
  return [values containsObject:value];
}

@end

That isn't complete by any means, but it gives you an idea of how you could make it.

Dave DeLong
thanks!!!! Your solution will fit in another case I have! :-)
Digital Robot
Or just making a model object for whatever has products, and giving it a `products` property by which it owns the array or set.
Peter Hosey
+2  A: 

You can put whatever you want as the object. Using objectForKey will return nil if the object is not in the dictionary and will return the object if it is. You can use it like this:

[myDict addObject:@"WHATEVER YOU WANT" forKey:@"banana"];
[myDict addObject:@"WHATEVER YOU WANT" forKey:@"orange"];
[myDict addObject:@"WHATEVER YOU WANT" forKey:@"grapes"];
..
..
..
if ([myDict objectForKey:@"banana"]) {
  // I have a banana
} 
if ([myDict objectForKey:@"orange"]) {
  // I have an orange
} 
if ([myDict objectForKey:@"grapes"]) {
  // I have grapes
}
coneybeare
thanks. All solutions are good but this is the simpler!!!!
Digital Robot
If you think that'll work for you, why not just use an NSSet?
bbum
+2  A: 

I agree with the other posters that you may be misunderstanding how dictionaries work. But on the off chance it's useful, here's how you could look to see if a specific object is present as a value, and for which key(s):

// assume the object you're looking for is in the variable myValue
NSArray *keys = [myDict allKeysForObject:myValue];
if( [keys count] ) {
  // do whatever ...
}
Sixten Otto
+1 It's not often I see a valid use case for `allKeysForObject:`. I've never used it myself.
Dave DeLong
good solution, thanks!
Digital Robot