# Is there a method to enumerate the keys/values of SystemUtilitiesHashTable

Lacking from the simple API of SystemUtilitiesHashTable is a method to enumerate the keys/values.

?SystemUtilitiesHash*



After creating a hash table

h = SystemUtilitiesHashTable[];
SystemUtilitiesHashTableAdd[h, "a", 1];


Various methods to extract its content fail.

h[[1]]
h
DownValues[h]


Any way out?

-
I wonder what HashTableGet[] does... :) – J. M. Jun 8 '13 at 15:17
@0x4A4D I think OP wants to list all available key-value pairs in the table, which I believe is not possible. – R. M. Jun 8 '13 at 15:21
If you want to be able to enumerate the contents, you're probably better off just to use ordinary downvalues rather than the SystemUtilitiesHashTable. – Oleksandr R. Jun 8 '13 at 19:44
Just to follow up on 0x4A4D, you have tried SystemUtilitiesHashTableGet[h, "a"]? – Seth Chandler Jun 9 '13 at 5:35

I'm sure there must be a better way, but this works:

h = SystemUtilitiesHashTable[];
SystemUtilitiesHashTableAdd[h, "a", 1];
SystemUtilitiesHashTableAdd[h, "b", 2];

ToExpression[ToString[h, InputForm], InputForm, Hold][[1, 2]]

{{"a", 1}, {"b", 2}}


Mr. Wizard provides a more terse version:

ToHeldExpression[ToString[h, InputForm]][[1, 2]]

-
Unless there is something like SparseArray[. . .]["NonzeroPositions"] for HashTable there very well may not be a better way. – Mr.Wizard Jun 9 '13 at 13:48
More terse: ToHeldExpression[ToString[h, InputForm]][[1, 2]] – Mr.Wizard Jun 9 '13 at 14:55
As with many things Mathematica I learned it from Leonid. It's an old function but still entirely, well, functional. – Mr.Wizard Jun 10 '13 at 10:13
+1. I still hope there is some more robust way though, since ToString-ToExpression transformation is not always robust. – Leonid Shifrin Jun 10 '13 at 10:28
@Leonid for testing purposes can you give an example where Simon's method fails? – Mr.Wizard Jun 10 '13 at 12:01

OP's question

Updating this post, the set of functions related to HashTable is in version 10.2:

$ContextPath = Prepend[$ContextPath, "SystemUtilities"];
?*HashTable*

HashTable      HashTableContainsQ   HashTableMapAt    HashTableSet


and is extended in version 10.3 to:

?*HashTable*

HashTable             HashTableGet      HashTableRemove
HashTableClone        HashTableMapAt    HashTableToAssociation
HashTableContainsQ    HashTableQ        HashTableValues


With 10.3, an easier way to extract keys/values, per OP's question, becomes available.

• Define a hash table and fill it in (10.2, 10.3):

h = HashTable[];


• Extract keys and values (10.3):

HashTableKeys[h]
HashTableValues[h]

(* {"h", "g"} *)
(* {"hello", 1} *)


• Make it an association (10.3) and use the functions Keys and Values:

asso = HashTableToAssociation[h]
(* <|"h" -> "hello", "g" -> 1|> *)

Keys[asso]
Values[asso]

(* {"h", "g"} *)
(* {"hello", 1} *)


What do other functions do?

This question has been covered to some extent in other posts (in particular, see the answer of Oleksandr R. in post #990). I recall below the definitions already addressed, and provide those that are new from 10.2.

HashTableSet changes the value of a key (10.2, 10.3):

HashTableSet[h, "h", "world"];
HashTableToAssociation[h]
(* <|"h" -> "world", "g" -> 1|> *)


HashTableRemove removes a pair key/value by referring to the key (10.2, 10.3):

HashTableRemove[h, "h"]
(* "world" *)

HashTableToAssociation[h]
(* <|"g" -> 1|> *)


HashTableGet gets the value of a key (10.2, 10.3):

HashTableGet[h, "g"]
(* 1 *)


HashTableContainsQ asks whether a key belongs to the hash table (10.2, 10.3):

HashTableContainsQ[h, "g"]
(* True *)


HashTableMapAt maps at a key a function on its associated value (10.2, 10.3):

HashTableToAssociation[h]
(* <|"g" -> 1|> *)

(* when existing *)
HashTableMapAt[h, "g", foo];
HashTableToAssociation[h]
(* <|"g" -> foo[1]|> *)

(* when not existing *)
HashTableMapAt[h, "h", "hello", "world"];
HashTableToAssociation[h]
(* <|"h" -> "hello"["world"], "g" -> foo[1]|> *)


HashTableClone clones a hash table and set it to a new one (10.3):

h2 = HashTableClone[h];
HashTableToAssociation[h2]
(* <|"h" -> "hello"["world"], "g" -> foo[1]|> *)


This function is particularly useful to avoid the following:

h3 = h;
HashTableToAssociation[h3]
(* <|"h" -> "hello"["world"], "g" -> foo[1]|> *)

HashTableToAssociation[h]
HashTableToAssociation[h2]
HashTableToAssociation[h3]

(* <|"f" -> a, "h" -> "hello"["world"], "g" -> foo[1]|> *)
(* <|"h" -> "hello"["world"], "g" -> foo[1]|> *)
(* <|"f" -> a, "h" -> "hello"["world"], "g" -> foo[1]|> *)


HashTableQ asks whether a given expression has a hash table structure (10.3):

HashTableQ[h2]
(* True *)


Hash tables and associations

Associations are introduced since version 10.0, so in principle one should prefer using them rather than hash tables. When there is a correspondence between an association function and a hash table function, the syntax of the former allows in general for more manipulations. Note also that more functions are available to manipulate associations.

Here is an equivalence between hash table and association functions (recall that "SystemUtilities" has been added in the context path):

(* Hash tables: *)    HashTableKeys
(* Associations: *)   Keys

(* Hash tables: *)    HashTableValues
(* Associations: *)   Values

(* Hash tables: *)    HashTableRemove
(* Associations: *)   KeyDrop

(* Hash tables: *)    HashTableGet
(* Associations: *)   Lookup, asso[key], asso[[Key[key]]]

(* Associations: *)   Association[asso, key -> value]

(* Hash tables: *)    HashTableSet
(* Associations: *)   asso[key] = ..., asso[[Key[key]]] = ...

(* Hash tables: *)    HashTableClone
(* Associations: *)   asso1 = asso2

(* Hash tables: *)    HashTableContainsQ
(* Associations: *)   KeyExistsQ

-
Nice answer! Are you sure you want it to be a community wiki? It will probably get a fair number of votes. :-) – Mr.Wizard Feb 4 at 14:22
@Mr.Wizard Thanks! Yes, I think it is better this way, in particular it may need updates from the community if new Mathematica versions modify or add some features to hash tables in the future. – Xavier Feb 4 at 14:28