How can I convert an NSArray to an NSDictionary, using an int field of the array's objects as key for the NSDictionary?
            Asked
            
        
        
            Active
            
        
            Viewed 6.6k times
        
    46
            
            
        6 Answers
77
            
            
        Try this magic:
NSDictionary *dict = [NSDictionary dictionaryWithObjects:records 
                                   forKeys:[records valueForKey:@"intField"]];
FYI this is possible because of this built-in feature:
@interface NSArray(NSKeyValueCoding)
/* Return an array containing the results of invoking -valueForKey: 
on each of the receiver's elements. The returned array will contain
NSNull elements for each instance of -valueForKey: returning nil.
*/
- (id)valueForKey:(NSString *)key;
        malhal
        
- 26,330
 - 7
 - 115
 - 133
 
- 
                    It's really a magic! Elegant and really handy solution! Just a note: Maybe better to use [records valueForKey:@"otherField"] not just records, as it will contains "intField" too. Anyway it's new for me even after years of coding... – BootMaker Jan 19 '18 at 16:02
 
53
            - (NSDictionary *) indexKeyedDictionaryFromArray:(NSArray *)array 
{
  id objectInstance;
  NSUInteger indexKey = 0U;
  NSMutableDictionary *mutableDictionary = [[NSMutableDictionary alloc] init];
  for (objectInstance in array)
    [mutableDictionary setObject:objectInstance forKey:[NSNumber numberWithUnsignedInt:indexKey++]];
  return (NSDictionary *)[mutableDictionary autorelease];
}
        Alex Reynolds
        
- 95,983
 - 54
 - 240
 - 345
 
9
            
            
        This adds a category extension to NSArray.  Needs C99 mode (which is the default these days, but just in case).
In a .h file somewhere that can be #imported by all..
@interface NSArray (indexKeyedDictionaryExtension)
- (NSDictionary *)indexKeyedDictionary
@end
In a .m file..
@implementation NSArray (indexKeyedDictionaryExtension)
- (NSDictionary *)indexKeyedDictionary
{
  NSUInteger arrayCount = [self count];
  id arrayObjects[arrayCount], objectKeys[arrayCount];
  [self getObjects:arrayObjects range:NSMakeRange(0UL, arrayCount)];
  for(NSUInteger index = 0UL; index < arrayCount; index++) { objectKeys[index] = [NSNumber numberWithUnsignedInteger:index]; }
  return([NSDictionary dictionaryWithObjects:arrayObjects forKeys:objectKeys count:arrayCount]);
}
@end
Example use:
NSArray *array = [NSArray arrayWithObjects:@"zero", @"one", @"two", NULL];
NSDictionary *dictionary = [array indexKeyedDictionary];
NSLog(@"dictionary: %@", dictionary);
Outputs:
2009-09-12 08:41:53.128 test[66757:903] dictionary: {
    0 = zero;
    1 = one;
    2 = two;
}
        johne
        
- 6,760
 - 2
 - 24
 - 25
 
- 
                    1I love using categories, so I'd preffer this solution instead of using a simple function because of the way of calling it directly on the object itself, as if it always knew that method. – Woofy Sep 19 '09 at 12:10
 
1
            
            
        - (NSDictionary *) indexKeyedDictionaryFromArray:(NSArray *)array
{
    NSMutableDictionary *mutableDictionary = [[NSMutableDictionary alloc] init];
    [array enumerateObjectsUsingBlock:
     ^(id obj, NSUInteger idx, BOOL *stop){
         NSNumber *index = [NSNumber numberWithInteger:idx];
         [mutableDictionary setObject:obj forKey:index];
     }];
    NSDictionary *result = [NSDictionary.alloc initWithDictionary:mutableDictionary];
    return result;
}
        AcornHacks
        
- 19
 - 4
 
1
            
            
        This is an example of creating a NSMutableDictionary from the employee list NSMutableArray:
 NSMutableArray *emloyees = [[NSMutableArray alloc]initWithObjects:@"saman",@"Ruchira",@"Rukshan",@"ishan",@"Harsha",@"Ghihan",@"Lakmali",@"Dasuni", nil];
 NSMutableDictionary *dict = [NSMutableDictionary dictionary];
 for (NSString *word in emloyees) {
 NSString *firstLetter = [[word substringToIndex:1] uppercaseString];
 letterList  = [dict objectForKey:firstLetter];
if (!letterList) {
    letterList = [NSMutableArray array];
    [dict setObject:letterList forKey:firstLetter];
}
[letterList addObject:word];}  NSLog(@"dic %@",dict);
        Alexander Abakumov
        
- 13,617
 - 16
 - 88
 - 129
 
        damith
        
- 33
 - 6
 
-1
            
            
        I have created a simple library, called Linq to ObjectiveC, which is a collection of methods that makes this kind of problem much easier to solve. In your case you need the Linq-to-ObjectiveC toDictionary method, where your 'int' field is specified via a key selector:
NSDictionary* dictionary = [sourceArray toDictionaryWithKeySelector:^id(id item) {
    return [item intField];
}];
This returns a dictionary where the keys are given by the intField in the source array.
        ColinE
        
- 68,894
 - 15
 - 164
 - 232