28

HashTables/HashMaps are one of the most (if not the most) useful of data-structures in existence. As such, one of the first things I investigated when starting to learn programming in Cocoa was how to create, populate, and read data from a hashtable.

To my surprise: all the documentation I've been reading on Cocoa/Objective-C programming doesn't seem to explain this much at all. As a Java developer that uses "java.util" as if it were a bodily function: I am utterly baffled by this.

So, if someone could provide me with a primer for creating, populating, and reading the contents of a hashtable: I would greatly appreciate it.

Ryan Delucchi
  • 7,718
  • 13
  • 48
  • 60
  • 2
    Technically the Objective-C language doesn't have hash tables or any kind of data structures beyond basic C-arrays. The Cocoa frameworks (in particular Foundation) do, however. – amrox Jan 23 '09 at 21:08
  • thanks for pointing that out. I have thusly updated the title of my question to reflect this. – Ryan Delucchi Jan 23 '09 at 21:15
  • If you look in /usr/include/objc, you will find that Objective-C does, in fact, have a hash table type. (Perhaps it's not listed in the documentation, but it is there in the headers.) – Peter Hosey Jan 25 '09 at 09:20
  • Still not part of the language Objective-C. – Niklas Berglund Oct 13 '13 at 19:04

5 Answers5

59

NSDictionary and NSMutableDictionary?

And here's a simple example:

NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
[dictionary setObject:anObj forKey:@"foo"];
[dictionary objectForKey:@"foo"];
[dictionary removeObjectForKey:@"foo"];
[dictionary release];
Jon Schneider
  • 25,758
  • 23
  • 142
  • 170
Martin Gordon
  • 36,329
  • 7
  • 58
  • 54
  • 5
    Note that, in true object-oriented fashion, the Cocoa classes are named for "what they do" rather than "how they're implemented" as HashTable, HashMap, and friends are in Java, C#, and so on. – Chris Hanson Jan 24 '09 at 20:04
  • 2
    C# calls it a Dictionary as well! – bobobobo Dec 08 '09 at 04:51
  • 2
    @Chris Hanson - In Java this often distinguishes an implementation, e.g. `Thread`, from an interface, e.g. `Runnable`. I find this convention promotes programming to interfaces. It may or may not be 'true object-oriented fashion' but is widely regarded as a good idea. – CurtainDog Jun 08 '12 at 08:10
  • @Chris Hanson - In Java it's called a "Map" (what it does), and there are multiple implementations provided such as "HashMap", "TreeMap", "LinkedHashMap". – TJez Nov 13 '14 at 06:32
12

You can try using an NSHashTable!

msgambel
  • 7,320
  • 4
  • 46
  • 62
Julius Guzy
  • 121
  • 1
  • 2
  • The NSHashTable - a simple list of values and the ability to find by key is exactly what I was looking for as (for my use case), I didn't need/want the extra "key/value" of the NSDictionary, I would have been storing the same value in the key and value or leaving the value empty if that's even possible. I just want to stuff values in the NSHashTable and then use [myHashTable containsObject:[NSNumber numberWithInteger:searchValue]] to see if the value exists. – Tim T Mar 24 '13 at 15:10
  • Tim T - I think what you're talking about is called an NSArray. You add values to the "hash table" with [array addObject:value] then check to see if it's contained with [array containsObject:value]. You can also use NSSet if you want the values to be unique. NSHashTable is for cases - totally legitimate, of course - where you want to include arbitrary pointers to non-objects and other edge-cases, and was originally added to avoid the memory "retain" which other collections call on added objects in order to support Cocoa's ill-fated venture into Garbage Collection (now removed). – SG1 Dec 13 '13 at 03:50
8

If you're using Leopard (and Cocoa's new Garbage Collection), you also want to take a look at NSMapTable.

Rajneesh071
  • 30,846
  • 15
  • 61
  • 74
Barry Wark
  • 107,306
  • 24
  • 181
  • 206
  • more info on NSMapTable: http://stackoverflow.com/questions/6904533/nsmaptable-and-nsmutabledictionary-differences/12186329#12186329 – Steph Thirion Aug 29 '12 at 20:57
7

In addition to NSDictionary, also check out NSSet for when you need a collection with no order and no duplicates.

Chris Hanson
  • 54,380
  • 8
  • 73
  • 102
3

Use NSHashTable from iOS 6.0+ SDK. The hash table is modeled after NSSet with the following differences: It can hold weak references to its members. Its members may be copied on input or may use pointer identity for equality and hashing. It can contain arbitrary pointers (its members are not constrained to being objects).

 NSHashTable *hashTable = [NSHashTable 
 hashTableWithOptions:NSPointerFunctionsCopyIn];
 [hashTable addObject:@"foo"];
 [hashTable addObject:@"bar"];
 [hashTable addObject:@100];
 [hashTable removeObject:@"bar"];
 NSLog(@"Members: %@", [hashTable allObjects]);

Use NSMapTable from iOS 6.0+ SDK. The map table is modeled after NSDictionary with the following differences: Keys and/or values are optionally held “weakly” such that entries are removed when one of the objects is reclaimed. Its keys or values may be copied on input or may use pointer identity for equality and hashing. It can contain arbitrary pointers (its contents are not constrained to being objects).

 id delegate = ...;
 NSMapTable *mapTable = [NSMapTable 
 mapTableWithKeyOptions:NSMapTableStrongMemory
                                         valueOptions:NSMapTableWeakMemory];
 [mapTable setObject:delegate forKey:@"foo"];
 NSLog(@"Keys: %@", [[mapTable keyEnumerator] allObjects]);
mylittleswift
  • 320
  • 2
  • 8