Reputation:
Being new to Cocoa, and probably not knowing all of the potential classes available that already have this functionality neatly wrapped in an OO class, here's an algorithm inquiry. What's the best bet to count how many times a particular key occurs in an array of multiple NSDictionary
instances?
Essentially my data structure (in this case an NSArray
) might contain several NSDictionary
instances at any given time, each one having the same keys, potentially different values. Some values repeat. I'd like to be able to know how many times a particular key/value appears. Example:
{
foo => 1,
bar => 2
}
{
foo => 1,
bar => 3
}
{
foo => 2,
bar => 1
}
In this case I'm interested that foo=>1
occured 2 times and foo=>2
occured 1 time. Is building an instance of NSCountedSet
the best way to go about this? Perhaps a C linked-list?
Upvotes: 1
Views: 9309
Reputation: 96353
NSCountedSet *keyCounts = [NSCountedSet set];
for (NSDictionary *dict in myDictionaries)
[keyCounts unionSet:[NSSet setWithArray:[dict allKeys]]];
Upvotes: 1
Reputation: 119164
NSDictionary * dict1 = [[NSDictionary alloc] initWithObjectsAndKeys:
[NSNumber numberWithInt:1], @"foo",
[NSNumber numberWithInt:2], @"bar", nil];
NSDictionary * dict2 = [[NSDictionary alloc] initWithObjectsAndKeys:
[NSNumber numberWithInt:1], @"foo",
[NSNumber numberWithInt:3], @"bar", nil];
NSDictionary * dict3 = [[NSDictionary alloc] initWithObjectsAndKeys:
[NSNumber numberWithInt:2], @"foo",
[NSNumber numberWithInt:1], @"bar", nil];
NSArray * arrayOfDictionaries = [[NSArray alloc] initWithObjects:
dict1, dict2, dict3, nil];
// count all keys in an array of dictionaries (arrayOfDictionaries):
NSMutableDictionary * countKeys = [[NSMutableDictionary alloc] initWithCapacity:0];
NSCountedSet * counts = [[NSCountedSet alloc] initWithCapacity:0];
NSArray * keys;
NSString * pairString;
NSString * countKey;
for (NSDictionary * dictionary in arrayOfDictionaries)
{
keys = [dictionary allKeys];
for (NSString * key in keys)
{
pairString = [NSString stringWithFormat:@"%@->%@", key, [dictionary valueForKey:key]];
if ([countKeys valueForKey:pairString] == nil)
{
[countKeys setValue:[NSString stringWithString:pairString] forKey:pairString];
}
countKey = [countKeys valueForKey:pairString];
{ [counts addObject:countKey]; }
}
}
NSLog(@"%@", counts);
[counts release];
[countKeys release];
[arrayOfDictionaries release];
[dict1 release];
[dict2 release];
[dict3 release];
Upvotes: 2
Reputation: 4171
You may want to rethink how you are structuring your data. I'd track something like this while adding to the NSArray instead of trying to discover it at a later time. You might create a new class to handle adding and removing the data so that you can keep your own counts of the data.
Upvotes: 4