Mathematica Stack Exchange is a question and answer site for users of Mathematica. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Lacking from the simple API of System`Utilities`HashTable is a method to enumerate the keys/values.

?System`Utilities`Hash*

HashTable   HashTableAdd    HashTableContainsQ  HashTableGet    HashTableRemove

After creating a hash table

h = System`Utilities`HashTable[];
System`Utilities`HashTableAdd[h, "a", 1];

Various methods to extract its content fail.

h[[1]]
h
DownValues[h]

Any way out?

share|improve this question
1  
I wonder what HashTableGet[] does... :) – J. M. Jun 8 '13 at 15:17
    
@J. M. 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
2  
If you want to be able to enumerate the contents, you're probably better off just to use ordinary downvalues rather than the System`Utilities`HashTable. – Oleksandr R. Jun 8 '13 at 19:44
    
Just to follow up on J. M., you have tried System`Utilities`HashTableGet[h, "a"]? – Seth Chandler Jun 9 '13 at 5:35
up vote 11 down vote accepted

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

h = System`Utilities`HashTable[];
System`Utilities`HashTableAdd[h, "a", 1];
System`Utilities`HashTableAdd[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]]
share|improve this answer
    
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
1  
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  
+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
1  
@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, "System`Utilities`"];
?*HashTable*

HashTable      HashTableContainsQ   HashTableMapAt    HashTableSet
HashTableAdd   HashTableGet         HashTableRemove 

and is extended in version 10.3 to:

?*HashTable*

HashTable             HashTableGet      HashTableRemove
HashTableAdd          HashTableKeys     HashTableSet
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[];
HashTableAdd[h, "g", 1]
HashTableAdd[h, "h", "hello"]

• 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]|> *)

HashTableAdd[h, "f", a]
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 "System`Utilities`" 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]]]

(* Hash tables: *)    HashTableAdd
(* 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
share|improve this answer
    
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

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.