Hash from two arrays: Difference between revisions

From Rosetta Code
Content added Content deleted
(→‎{{header|REXX}}: add REXX language. -- ~~~~)
Line 854: Line 854:
<lang raven>[ 'a' 'b' 'c' ] as $keys [ 1 2 3 ] as $vals
<lang raven>[ 'a' 'b' 'c' ] as $keys [ 1 2 3 ] as $vals
$keys $vals combine as $hash</lang>
$keys $vals combine as $hash</lang>

=={{header|REXX}}==
<lang rexx>
/*demonstrate hashing an array.*/
/*names of the 9 regular polygons*/

values='triangle quadrilateral pentagon hexagon heptagon octagon nonagon decagon dodecagon'
keys ='won too thuhree vour phive sicks zeaven ate nein'

/*superflous blanks added to humorous keys just 'cause it looks prettier*/


call hash values,keys /*hash the keys to the values. */

parse arg query . /*what was specified on cmd line.*/
if query=='' then exit /*nothing, then let's leave Dodge*/

say copies('─',40) /*show a sep for visual fidelity.*/
say 'key=' query " value=" hash.query /*show & tell time.*/
say copies('─',40) /*show a sep for visual fidelity.*/
exit

/*─────────────────────────────────────HASH subroutine──────────────────*/
hash: procedure expose hash.; parse arg v,k,hash.
do j=1 until map=''
map=word(k,j)
hash.map=word(v,j)
end
return
</lang>
Output when using the input of:
<br><br>
phive
<pre style="height:15ex;overflow:scroll">
────────────────────────────────────────
key= phive value= heptagon
────────────────────────────────────────
</pre>


=={{header|Ruby}}==
=={{header|Ruby}}==

Revision as of 22:54, 22 March 2012

Task
Hash from two arrays
You are encouraged to solve this task according to the task description, using any language you may know.

Using two Arrays of equal length, create a Hash object where the elements from one array (the keys) are linked to the elements of the other (the values)

ActionScript

<lang actionscript>package {

   public class MyClass
   {
       public static function main():Void
       {
           var hash:Object = new Object();
           var keys:Array = new Array("a", "b", "c");
           var values:Array = new Array(1, 2, 3);
           
           for (var i:int = 0; i < keys.length(); i++)
               hash[keys[i]] = values[i]; 
       }
   }

}</lang>

Ada

Works with: GNAT version GPL 2007

<lang ada>with Ada.Strings.Hash; with Ada.Containers.Hashed_Maps; with Ada.Text_Io; with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;

procedure Hash_Map_Test is

  function Equivalent_Key (Left, Right : Unbounded_String) return Boolean is
  begin
     return Left = Right;
  end Equivalent_Key;
 
  function Hash_Func(Key : Unbounded_String) return Ada.Containers.Hash_Type is
  begin
     return Ada.Strings.Hash(To_String(Key));
  end Hash_Func;
 
  package My_Hash is new Ada.Containers.Hashed_Maps(Key_Type => Unbounded_String,
     Element_Type => Unbounded_String,
     Hash => Hash_Func,
     Equivalent_Keys => Equivalent_Key);
    
  type String_Array is array(Positive range <>) of Unbounded_String;
    
  Hash : My_Hash.Map;
  Key_List : String_Array := (To_Unbounded_String("foo"), 
     To_Unbounded_String("bar"),
     To_Unbounded_String("val"));
    
  Element_List : String_Array := (To_Unbounded_String("little"), 
     To_Unbounded_String("miss"), 
     To_Unbounded_String("muffet"));
    

begin

  for I in Key_List'range loop
     Hash.Insert(Key => (Key_List(I)),
        New_Item => (Element_List(I)));
  end loop;
  for I in Key_List'range loop
     Ada.Text_Io.Put_Line(To_String(Key_List(I)) & " => " &
        To_String(Hash.Element(Key_List(I))));
  end loop;
 

end Hash_Map_Test;</lang>

Argile

Works with: Argile version 1.1.0

<lang Argile>use std, array, hash

let keys = @["hexadecimal" "decimal" "octal" "binary"] let values = @[0xa 11 014 0b1101] (: 10 11 12 13 :) let hash = new hash of int for each val int i from 0 to 3

 hash[keys[i]] = values[i]

del hash hash</lang>

AutoHotkey

<lang AutoHotkey>array1 := ["two", "three", "apple"] array2 := [2, 3, "fruit"] hash := {} Loop % array1.maxIndex()

  hash[array1[A_Index]] := array2[A_Index]

MsgBox % hash["apple"] "`n" hash["two"]</lang>

AWK

Awk arrays are used for both lists and hash maps. <lang awk>$ awk 'BEGIN{split("one two three",a);

            split("1 2 3",b);
            for(i=1;i in a;i++){c[a[i]]=b[i]};
            for(i in c)print i,c[i]
            }'

three 3 two 2 one 1</lang>

Bracmat

<lang bracmat> two three apple:?arr1 & 2 3 fruit:?arr2 & new$hash:?H & whl

 ' ( !arr1:%?k ?arr1
   & !arr2:%?v ?arr2
   & (H..insert)$(!k.!v)
   )

& (H..forall)$out & ; </lang> Output:

apple.fruit
three.3
two.2

Brat

<lang brat>zip = { keys, values | h = [:] keys.each_with_index { key, index | h[key] = values[index] }

h }

p zip [1 2 3] [:a :b :c] #Prints [1: a, 2: b, 3: c]</lang>

C

There likely exist libraries that can be used for creating hashes that are better than the following implementation. There are also better functions for obtaining hash values from strings. The following implementation tries to be somewhat generic to facilitate using alternative key and value types. <lang c>#include <stdio.h>

  1. include <stdlib.h>
  2. include <string.h>
  1. define KeyType const char *
  2. define ValType int
  1. define HASH_SIZE 4096

// hash function useful when KeyType is char * (string) unsigned strhashkey( const char * key, int max) {

   unsigned h=0;
   unsigned hl, hr;
   while(*key) {
       h += *key;
       hl= 0x5C5 ^ (h&0xfff00000 )>>18;
       hr =(h&0x000fffff );
       h = hl ^ hr ^ *key++;
   }
   return h % max;

}

typedef struct sHme {

   KeyType    key;
   ValType    value;
   struct sHme  *link;

} *MapEntry;

typedef struct he {

   MapEntry  first, last;

} HashElement;

HashElement hash[HASH_SIZE];

typedef void (*KeyCopyF)(KeyType *kdest, KeyType ksrc); typedef void (*ValCopyF)(ValType *vdest, ValType vsrc); typedef unsigned (*KeyHashF)( KeyType key, int upperBound ); typedef int (*KeyCmprF)(KeyType key1, KeyType key2);

void HashAddH( KeyType key, ValType value,

       KeyCopyF copyKey, ValCopyF copyVal, KeyHashF hashKey, KeyCmprF keySame )

{

   unsigned hix = (*hashKey)(key, HASH_SIZE);
   MapEntry m_ent;
   for (m_ent= hash[hix].first;
           m_ent && !(*keySame)(m_ent->key,key); m_ent=m_ent->link);
   if (m_ent) {
       (*copyVal)(&m_ent->value, value);
   }
   else {
       MapEntry last;
       MapEntry hme = malloc(sizeof(struct sHme));
       (*copyKey)(&hme->key, key);
       (*copyVal)(&hme->value, value);
       hme->link = NULL;
       last = hash[hix].last;
       if (last) {

// printf("Dup. hash key\n");

           last->link = hme;
       }
       else
           hash[hix].first = hme;
       hash[hix].last = hme;
   }

}

int HashGetH(ValType *val, KeyType key, KeyHashF hashKey, KeyCmprF keySame ) {

   unsigned hix = (*hashKey)(key, HASH_SIZE);
   MapEntry m_ent;
   for (m_ent= hash[hix].first;
           m_ent && !(*keySame)(m_ent->key,key); m_ent=m_ent->link);
   if (m_ent) {
       *val = m_ent->value;
   }
   return (m_ent != NULL);

}

void copyStr(const char**dest, const char *src) {

   *dest = strdup(src);

} void copyInt( int *dest, int src) {

   *dest = src;

} int strCompare( const char *key1, const char *key2) {

   return strcmp(key1, key2) == 0;

}

void HashAdd( KeyType key, ValType value ) {

   HashAddH( key, value, &copyStr, &copyInt, &strhashkey, &strCompare);

}

int HashGet(ValType *val, KeyType key) {

   return HashGetH( val, key, &strhashkey, &strCompare);

}

int main() {

   static const char * keyList[] = {"red","orange","yellow","green", "blue", "violet" };
   static int valuList[] = {1,43,640, 747, 42, 42};
   int ix;
   for (ix=0; ix<6; ix++) {
       HashAdd(keyList[ix], valuList[ix]);
   }
   return 0;

}</lang>

C++

Technically a std::map is a binary search tree, not a hash table, but it provides the same functionality. The C++11 standard incorporates hash tables. To use a hash table in C++11, simply change std::map to std::unordered_map. The core idea, turning two sequences into an associative mapping, is valid either way.

<lang cpp>#include <map>

  1. include <string>

int main( int argc, char* argv[] ) {

std::string keys[] = { "1", "2", "3" } ;
std::string vals[] = { "a", "b", "c" } ;

std::map< std::string, std::string > hash ;

for( int i = 0 ; i < 3 ; i++ )
{
 hash[ keys[i] ] = vals[i] ;
}

}</lang>

Alternatively: <lang cpp>#include <map> // for std::map

  1. include <algorithm> // for std::transform
  2. include <string> // for std::string
  3. include <utility> // for std::make_pair

int main() {

 std::string keys[] = { "one", "two", "three" };
 std::string vals[] = { "foo", "bar", "baz" };
 std::map<std::string, std::string> hash;
 std::transform(keys, keys+3,
                vals,
                std::inserter(hash, hash.end()),
                std::make_pair<std::string, std::string>);

}</lang>

C#

<lang csharp>System.Collections.HashTable h = new System.Collections.HashTable();

string[] arg_keys = {"foo","bar","val"}; string[] arg_values = {"little", "miss", "muffet"};

//Some basic error checking int arg_length = 0; if ( arg_keys.Length == arg_values.Length ) {

 arg_length = arg_keys.Length;

}

for( int i = 0; i < arg_length; i++ ){

 h.add( arg_keys[i], arg_values[i] ); 

}</lang>

Alternate way of adding values

<lang csharp>for( int i = 0; i < arg_length; i++ ){

 h[ arg_keys[i] ] = arg_values[i]; 

}</lang>

Clojure

<lang lisp>(zipmap [\a \b \c] [1 2 3])</lang>

CoffeeScript

<lang coffeescript>

 keys = ['a','b','c']
 values = [1,2,3]
 map = {}
 map[key] = values[i] for key, i in keys

</lang>

ColdFusion

<lang ColdFusion><cfscript> function makeHash(keyArray, valueArray) {

 var x = 1;
 var result = {};
 for( ; x <= ArrayLen(keyArray); x ++ ) {
   result[keyArray[x]] = valueArray[x];
 }
 return result;

}

keyArray = ['a', 'b', 'c']; valueArray = [1, 2, 3]; map = makeHash(keyArray, valueArray); </cfscript></lang>

Common Lisp

<lang lisp>(defun rosetta-code-hash-from-two-arrays (vector-1 vector-2 &key (test 'eql))

 (assert (= (length vector-1) (length vector-2)))
 (let ((table (make-hash-table :test test :size (length vector-1))))
   (map nil (lambda (k v) (setf (gethash k table) v))
            vector-1 vector-2)
   table))</lang>

Or, using cl:loop:

<lang lisp>(defun rosetta-code-hash-from-two-arrays (vector-1 vector-2 &key (test 'eql))

 (loop initially (assert (= (length vector-1) (length vector-2)))
       with table = (make-hash-table :test test :size (length vector-1))
       for k across vector-1
       for v across vector-2
       do (setf (gethash k table) v)
       finally (return table)))</lang>

In Common Lisp terminology, a vector is a one-dimensional array.

D

<lang d>import std.range: zip;

void main() {

   auto keys = ["one", "two", "three"];
   auto values  = [1, 2, 3];
   int[string] hash;
   foreach (idx, key; keys)
       hash[key] = values[idx];
   // alternative using zip
   foreach (pair; zip(keys, values))
       hash[pair[0]] = pair[1];

}</lang>

E

<lang e>def keys := ["one", "two", "three"] def values := [1, 2, 3] __makeMap.fromColumns(keys, values)</lang>

F#

<lang fsharp>HashMultiMap(Array.zip [|"foo"; "bar"; "baz"|] [|16384; 32768; 65536|], HashIdentity.Structural)</lang>

Factor

<lang factor>USING: hashtables ; { "one" "two" "three" } { 1 2 3 } zip >hashtable</lang>

Falcon

<lang falcon> keys = [ 'a', 'b', 'c', 'd' ] values = [ 1, 2, 3, 4 ] hash = [ => ] for i in [ 0 : keys.len() ]: hash[ keys[ i ] ] = values[ i ] </lang>

Fantom

<lang fantom> class Main {

 public static Void main ()
 {
   keys := [1,2,3,4,5]
   values := ["one", "two", "three", "four", "five"]
   // create an empty map
   map := [:]  
   // add the key-value pairs to it
   keys.size.times |Int index|
   {
     map.add(keys[index], values[index])
   }
 }

} </lang>

Go

<lang go>keys := []string{"a", "b", "c"} vals := []int{1, 2, 3} hash := make(map[string]int)

for i := 0; i < len(keys); i++ {

   hash[keys[i]] = vals[i]

}</lang>

Groovy

<lang groovy>keys = ['a','b','c'] vals = ['aaa', 'bbb', 'ccc'] hash = [:] keys.eachWithIndex { key, i ->

hash[key] = vals[i] 

}</lang>

Haskell

Works with: GHCi version 6.6

<lang haskell>import Data.Map

makeMap ks vs = fromList $ zip ks vs mymap = makeMap ['a','b','c'] [1,2,3]</lang>

Icon and Unicon

<lang Icon>link ximage # to format the structure

procedure main(arglist) #: demonstrate hash from 2 lists local keylist

if *arglist = 0 then arglist := [1,2,3,4] # ensure there's a list every put(keylist := [], "key-" || !arglist) # make keys for each entry

every (T := table())[keylist[ i := 1 to *keylist ]] := arglist[i] # create the hash table

write(ximage(T)) # show result end</lang>

Ioke

<lang ioke>{} addKeysAndValues([:a, :b, :c], [1, 2, 3])</lang>

J

Solution: <lang j>hash=: vals {~ keys&i.</lang> For example:

<lang j> keys=: 10?.100

  vals=: > ;:'zero one two three four five six seven eight nine'
  hash=: vals {~ keys&i.
  keys

46 99 23 62 42 44 12 5 68 63

  $vals

10 5

  hash 46

zero

  hash 99

one

  hash 63 5 12 5 23

nine seven six seven two</lang> Here, keys is a list of 10 integers between 0 and 99 chosen at random without repetition, and vals is a 10 by 5 character matrix.

Java

<lang java>import java.util.HashMap; public static void main(String[] args){ String[] keys= {"a", "b", "c"}; int[] vals= {1, 2, 3}; HashMap<String, Integer> hash= new HashMap<String, Integer>();

for(int i= 0; i < keys.length; i++){ hash.put(keys[i], vals[i]); } }</lang>

JavaScript

<lang javascript>var keys = ['a', 'b', 'c']; var values = [1, 2, 3]; var map = {}; for(var i in keys) {

 map[ keys[i] ] = values[i];

}</lang>

K

The keys in a dictionary must be a symbol. <lang K> a: `zero `one `two / symbols

  b: 0 1 2
  d:. a,'b  / create the dictionary

.((`zero;0;)

 (`one;1;)
 (`two;2;))
  d[`one]

1</lang>

Here we use integers as keys (which must be converted to symbols) and strings as values (here also converted to symbols).

<lang K> keys: !10 / 0..9

  split:{1_'(&x=y)_ x:y,x}
  vals:split["zero one two three four five six seven eight nine";" "]
  s:{`$$x}  / convert to symbol
  d:. (s'keys),'s'vals

.((`"0";`zero;)

 (`"1";`one;)
 (`"2";`two;)
 (`"3";`three;)
 (`"4";`four;)
 (`"5";`five;)
 (`"6";`six;)
 (`"7";`seven;)
 (`"8";`eight;)
 (`"9";`nine;))
  $d[s 1] / leading "$" converts back to string

"one"</lang>

Lua

<lang lua> function(keys,values)

 local t = {}
 for i=1, #keys do
   t[keys[i]] = values[i]
 end

end </lang>

Mathematica

<lang Mathematica>Map[(Hash[Part[#, 1]] = Part[#, 2]) &,

Transpose[{{1, 2, 3}, {"one", "two", "three"}}]]

?? Hash ->Hash[1]=one ->Hash[2]=two ->Hash[3]=three</lang>

Nemerle

<lang Nemerle>using System; using System.Console; using Nemerle.Collections; using Nemerle.Collections.NCollectionsExtensions;

module AssocArray {

   Main() : void
   {
       def list1 = ["apples", "oranges", "bananas", "kumquats"];
       def list2 = [13, 34, 12];
       def inventory = Hashtable(ZipLazy(list1, list2));
       foreach (item in inventory)
           WriteLine("{0}:   {1}", item.Key, item.Value);
   }

}</lang>

Objeck

<lang objeck> use Structure;

bundle Default {

 class HashOfTwo {
   function : Main(args : System.String[]) ~ Nil {
     keys := ["1", "2", "3"];
     vals := ["a", "b", "c"];
     hash := StringHash->New();
     each(i : vals) {
       hash->Insert(keys[i], vals[i]->As(Base));
     };
   }
 }

} </lang>

Objective-C

<lang objc>NSArray *keys = [NSArray arrayWithObjects:@"a", @"b", @"c", nil]; NSArray *values = [NSArray arrayWithObjects:[NSNumber numberWithInt:1],

                                           [NSNumber numberWithInt:2],
                                           [NSNumber numberWithInt:3], nil];

NSDictionary *dict = [NSDictionary dictionaryWithObjects:values forKeys:keys];</lang>

OCaml

The idiomatic solution uses lists rather than arrays.

<lang ocaml>let keys = [ "foo"; "bar"; "baz" ] and vals = [ 16384; 32768; 65536 ] and hash = Hashtbl.create 0;;

List.iter2 (Hashtbl.add hash) keys vals;;</lang>

In the extremely unlikely event that it was actually necessary to use arrays, the solution would become slightly less elegant: (except using the ExtLib which provides the equivalent Array.iter2)

<lang ocaml>let keys = [| "foo"; "bar"; "baz" |] and vals = [| 16384; 32768; 65536 |] and hash = Hashtbl.create 0;;

for i = 0 to Array.length keys - 1 do

 Hashtbl.add hash keys.(i) vals.(i)

done;;</lang>

In either case, an exception is raised if the inputs are different lengths.

If you want to use functional binary search trees instead of hash tables:

<lang ocaml>module StringMap = Map.Make (String);;

let keys = [ "foo"; "bar"; "baz" ] and vals = [ 16384; 32768; 65536 ] and map = StringMap.empty;;

let map = List.fold_right2 StringMap.add keys vals map;;</lang>

Oz

<lang oz>declare

 fun {ZipRecord Keys Values}
    {List.toRecord unit {List.zip Keys Values MakePair}}
 end
 fun {MakePair A B}
    A#B
 end

in

 {Show {ZipRecord [a b c] [1 2 3]}}</lang>

Perl

<lang perl>my @keys = qw(a b c); my @vals = (1, 2, 3); my %hash; @hash{@keys} = @vals;</lang>

Alternatively, using

:

<lang perl>use List::MoreUtils qw(zip); my %hash = zip @keys, @vals;</lang>

Perl 6

Works with: Rakudo version #23 "Lisbon"

<lang perl6>my @keys = <a b c d e>; my @vals = ^5; my %hash = @keys Z @vals;</lang>

Alternatively:

<lang perl6>my %hash; %hash{@keys} = @vals;</lang>

To create an anonymous hash value, you can use Z as a "zipwith" metaoperator on the => pair composer:

<lang perl6>{ <a b c d e> Z=> ^5 }</lang>

PHP

Works with: PHP version 5

<lang php>$keys = array('a', 'b', 'c'); $values = array(1, 2, 3); $hash = array_combine($keys, $values);</lang>

Works with: PHP version 4

<lang php>$keys = array('a', 'b', 'c'); $values = array(1, 2, 3); $hash = array(); for ($idx = 0; $idx < count($keys); $idx++) {

 $hash[$keys[$idx]] = $values[$idx];

}</lang>

PicoLisp

<lang PicoLisp>(let (Keys '(one two three) Values (1 2 3))

  (mapc println
     (mapcar cons Keys Values) ) )</lang>

Output:

(one . 1)
(two . 2)
(three . 3)

Pop11

<lang pop11>vars keys = { 1 a b c}; vars vals = { 2 3 valb valc}; vars i;

Create hash table

vars ht = newmapping([], 500, 0, true);

Loop over input arrays (vectors)

for i from 1 to length(keys) do

 vals(i) -> ht(keys(i));

endfor;</lang>

PostScript

Library: initlib

<lang postscript> % push our arrays

[/a /b /c /d /e] [1 2 3 4 5] 

% create a dict with it {aload pop} dip let currentdict end % show that we have created the hash

{= =} forall

</lang>

PowerShell

<lang powershell>function create_hash ([array] $keys, [array] $values) {

   $h = @{}
   if ($keys.Length -ne $values.Length) {
       Write-Error -Message "Array lengths do not match" `
                   -Category InvalidData `
                   -TargetObject $values
   } else {
       for ($i = 0; $i -lt $keys.Length; $i++) {
           $h[$keys[$i]] = $values[$i]
       }
   }
   return $h

}</lang>

Prolog

<lang prolog>% this one with side effect hash table creation

-dynamic hash/2.

make_hash([],[]). make_hash([H|Q],[H1|Q1]):- assert(hash(H,H1)), make_hash(Q,Q1).

-make_hash([un,deux,trois],[[a,b,c],[d,e,f],[g,h,i]])


% this one without side effects

make_hash_pure([],[],[]). make_hash_pure([H|Q],[H1|Q1],[hash(H,H1)|R]):- make_hash_pure(Q,Q1,R).

-make_hash_pure([un,deux,trois],[[a,b,c],[d,e,f],[g,h,i]],L),findall(M,(member(M,L),assert(M)),L).</lang>

PureBasic

<lang PureBasic>Dim keys.s(3) Dim vals.s(3) NewMap Hash.s()

keys(0)="a" : keys(1)="b" : keys(2)="c" : keys(3)="d" vals(0)="1" : vals(1)="2" : vals(2)="3" : vals(3)="4" For n = 0 To 3

   Hash(keys(n))= vals(n)

Next ForEach Hash()

  Debug Hash()

Next</lang>

Python

Works with: Python version 2.2+

<lang python>keys = ['a', 'b', 'c'] values = [1, 2, 3] hash = dict(zip(keys, values))

  1. Lazily, Python 2.3+, not 3.x:

from itertools import izip hash = dict(izip(keys, values))</lang>

Works with: Python version 3.0+

Shows off the dict comprehensions in Python 3: <lang python>keys = ['a', 'b', 'c'] values = [1, 2, 3] hash = {key: value for key, value in zip(keys, values)}</lang>

Works with: Python version 2.0+

<lang python>keys = ['a', 'b', 'c'] values = [1, 2, 3] hash = {} for k,v in zip(keys, values):

   hash[k] = v</lang>

The original (Ruby) example uses a range of different types as keys. Here is similar in python (run at the shell): <lang python>>>> class Hashable(object): def __hash__(self): return id(self) ^ 0xBEEF


>>> my_inst = Hashable() >>> my_int = 1 >>> my_complex = 0 + 1j >>> my_float = 1.2 >>> my_string = "Spam" >>> my_bool = True >>> my_unicode = u'Ham' >>> my_list = ['a', 7] >>> my_tuple = ( 0.0, 1.4 ) >>> my_set = set(my_list) >>> def my_func(): pass

>>> class my_class(object): pass

>>> keys = [my_inst, my_tuple, my_int, my_complex, my_float, my_string, my_bool, my_unicode, frozenset(my_set), tuple(my_list), my_func, my_class] >>> values = range(12) >>> d = dict(zip(keys, values)) >>> for key, value in d.items(): print key, ":", value

1 : 6 1j : 3 Ham : 7 Spam : 5 (0.0, 1.3999999999999999) : 1 frozenset(['a', 7]) : 8 1.2 : 4 ('a', 7) : 9 <function my_func at 0x0128E7B0> : 10 <class '__main__.my_class'> : 11 <__main__.Hashable object at 0x012AFC50> : 0 >>> # Notice that the key "True" disappeared, and its value got associated with the key "1" >>> # This is because 1 == True in Python, and dictionaries cannot have two equal keys</lang>

R

Assuming that the keys are coercible to character form, we can simply use the names attribute to create a hash. This example is taken from the Wikipedia page on hash tables. <lang r># Set up hash table keys <- c("John Smith", "Lisa Smith", "Sam Doe", "Sandra Dee", "Ted Baker") values <- c(152, 1, 254, 152, 153) names(values) <- keys

  1. Get value corresponding to a key

values["Sam Doe"] # vals["Sam Doe"]

  1. Get all keys corresponding to a value

names(values)[values==152] # "John Smith" "Sandra Dee"</lang>

Racket

<lang scheme>(make-hash

(map cons 
     '("a" "b" "c" "d") 
     '(1 2 3 4)))</lang>

Raven

<lang raven>[ 'a' 'b' 'c' ] as $keys [ 1 2 3 ] as $vals $keys $vals combine as $hash</lang>

REXX

<lang rexx> /*demonstrate hashing an array.*/

                                      /*names of the 9 regular polygons*/

values='triangle quadrilateral pentagon hexagon heptagon octagon nonagon decagon dodecagon' keys ='won too thuhree vour phive sicks zeaven ate nein'

/*superflous blanks added to humorous keys just 'cause it looks prettier*/


call hash values,keys /*hash the keys to the values. */

parse arg query . /*what was specified on cmd line.*/ if query== then exit /*nothing, then let's leave Dodge*/

say copies('─',40) /*show a sep for visual fidelity.*/ say 'key=' query " value=" hash.query /*show & tell time.*/ say copies('─',40) /*show a sep for visual fidelity.*/ exit

/*─────────────────────────────────────HASH subroutine──────────────────*/ hash: procedure expose hash.; parse arg v,k,hash.

        do j=1 until map=
        map=word(k,j)
        hash.map=word(v,j)
        end

return </lang> Output when using the input of:

phive
────────────────────────────────────────
key= phive         value= heptagon
────────────────────────────────────────

Ruby

<lang ruby>keys=['hal',666,[1,2,3]] vals=['ibm','devil',123]

if RUBY_VERSION >= '1.8.7'

 # Easy way, but needs Ruby 1.8.7 or later.
 hash = Hash[keys.zip(vals)]

else

 hash = keys.zip(vals).inject({}) {|h, kv| h.store(*kv); h }

end

p hash # => {"hal"=>"ibm", 666=>"devil", [1, 2, 3]=>123}

  1. retrieve the value linked to the key [1,2,3]

puts hash[ [1,2,3] ] # => 123</lang>

Or define a new method in class Array:

<lang ruby>class Array

 def zip_hash(other)
   Hash[*(0...self.size).inject([]) { |arr, ix|
          arr.push(self[ix], other[ix]) } ]
 end

end

hash = %W{ a b c }.zip_hash( %W{ 1 2 3 } ) p hash # => {"a"=>"1", "b"=>"2", "c"=>"3"}</lang>

Reference from Ruby Array to Hash

Sather

<lang sather>class ZIPPER{K,E} is

 zip(k:ARRAY{K}, e:ARRAY{E}) :MAP{K, E} 
   pre k.size = e.size
 is
   m :MAP{K, E} := #;
   loop m[k.elt!] := e.elt!; end;
   return m;    
 end;

end;

class MAIN is

 main is
   keys:ARRAY{STR} := |"one", "three", "four"|;
   values:ARRAY{INT} := |1, 3, 4|;
   m ::= ZIPPER{STR,INT}::zip(keys, values);
   loop 
     #OUT + m.pair! + " "; 
   end;
   #OUT + "\n";
 end;

end;</lang>

Scala

<lang scala>val keys = Array(1, 2, 3) val values = Array("A", "B", "C") val map = keys.zip(values).toMap</lang>

Scheme

Using SRFI 69: <lang scheme>(define (lists->hash-table keys values . rest)

 (apply alist->hash-table (map cons keys values) rest))</lang>

Seed7

<lang seed7>$ include "seed7_05.s7i";

const type: numericHash is hash [string] integer; var numericHash: myHash is numericHash.value;

const proc: main is func

 local
   var array string: keyList is [] ("one", "two", "three");
   var array integer: valueList is [] (1, 2, 3);
   var integer: number is 0;
 begin
   for number range 1 to length(keyList) do
     myHash @:= [keyList[number]] valueList[number];
   end for;
 end func;</lang>

Smalltalk

Works with: GNU Smalltalk

<lang smalltalk>Array extend [

 dictionaryWithValues: array [ |d|
   d := Dictionary new.
   1 to: ((self size) min: (array size)) do: [:i|
     d at: (self at: i) put: (array at: i).
   ].
   ^ d
 ]

].


({ 'red' . 'one' . 'two' }

dictionaryWithValues: { '#ff0000'. 1. 2 }) displayNl.</lang>

SNOBOL4

Works with: Macro Spitbol
Works with: Snobol4+
Works with: CSnobol

<lang SNOBOL4>* # Fill arrays

       keys = array(5); vals = array(5)
       ks = 'ABCDE'; vs = '12345'

kloop i = i + 1; ks len(1) . keys = :s(kloop) vloop j = j + 1; vs len(1) . vals<j> = :s(vloop)

  • # Create hash
       hash = table(5)

hloop k = k + 1; hash<keys<k>> = vals<k> :s(hloop)

  • # Test and display
       ts = 'ABCDE'

tloop ts len(1) . ch = :f(out)

       str = str ch ':' hash<ch> ' ' :(tloop)

out output = str end</lang>

Output:

A:1 B:2 C:3 D:4 E:5

Standard ML

Works with: SML/NJ

Using functional binary search trees instead of hash tables:

<lang sml>structure StringMap = BinaryMapFn (struct

                                    type ord_key = string
                                    val compare = String.compare
                                  end);

val keys = [ "foo", "bar", "baz" ] and vals = [ 16384, 32768, 65536 ] and myMap = StringMap.empty;

val myMap = foldl StringMap.insert' myMap (ListPair.zipEq (keys, vals));</lang>

Works with: SML/NJ

Using hash tables:

<lang sml>exception NotFound;

val keys = [ "foo", "bar", "baz" ] and vals = [ 16384, 32768, 65536 ] and hash = HashTable.mkTable (HashString.hashString, op=) (42, NotFound);

ListPair.appEq (HashTable.insert hash) (keys, vals);</lang>

Tcl

Arrays in Tcl are automatically associative, i.e. there are no "not hashed arrays". If we can take "arrays of equal length" to mean "lists of equal length", then the task might look like this: <lang tcl>set keys [list fred bob joe] set values [list barber plumber tailor] array set arr {} foreach a $keys b $values { set arr($a) $b }</lang> Alternatively, a dictionary could be used: <lang tcl>foreach a $keys b $values {

   dict set jobs $a $b

}</lang>

TXR

<lang txr>@(do (defun hash-from-two (vec1 vec2 equal-based-p)

      (let ((table (make-hash nil nil equal-based-p)))
        (for ((i 0)) ((< i (length vec1)) table) ((inc i))
          (set (gethash table (vecref vec1 i) 0) 
               (vecref vec2 i))))))

@(bind hash @(hash-from-two #(a b c) #(1 2 3) nil)) @(bind (keys vals) @(let (k v)

                     (dohash (key val hash (list k v))
                       (push key k)
                       (push val v))))</lang>
$ ./txr rosetta/hash-from-two.txr 
hash="#<hash: 175bc40>"
keys[0]="a"
keys[1]="b"
keys[2]="c"
vals[0]="1"
vals[1]="2"
vals[2]="3"

UnixPipes

Using a sorted file as an associative array (see Creating an associative array for usage.)

<lang bash>cat <<VAL >p.values apple boy cow dog elephant VAL

cat <<KEYS >p.keys a b c d e KEYS

paste -d\ <(cat p.values | sort) <(cat p.keys | sort)</lang>

Ursala

There's a built in operator for this. <lang Ursala>keys = <'foo','bar','baz'> values = <12354,145430,76748>

hash_function = keys-$values</lang> test program: <lang Ursala>#cast %nL

test = hash_function* <'bar','baz','foo','bar'></lang> output:

<145430,76748,12354,145430>

Vala

Library: Gee

<lang vala> using Gee;

void main(){

   // mostly copied from C# example                                            
   var hashmap = new HashMap<string, string>();
   string[] arg_keys = {"foo", "bar", "val"};
   string[] arg_values = {"little", "miss", "muffet"};
   if (arg_keys.length	== arg_values.length ){

for (int i = 0; i < arg_keys.length; i++){

           hashmap[arg_keys[i]] = arg_values[i];

}

   }

} </lang>

VBScript

VBScript (and Visual Basic in general) calls hashes "dictionary objects".

<lang vb>Set dict = CreateObject("Scripting.Dictionary") os = Array("Windows", "Linux", "MacOS") owner = Array("Microsoft", "Linus Torvalds", "Apple") For n = 0 To 2

   dict.Add os(n), owner(n)

Next MsgBox dict.Item("Linux") MsgBox dict.Item("MacOS") MsgBox dict.Item("Windows")</lang>

Output (in message boxes):

Linus Torvalds
Apple
Microsoft

Visual Basic

Translation of: VBScript

The VBScript version can be used in Visual Basic unchanged, although it requires a reference to the Microsoft Scripting Runtime (scrrun.dll).

Alternately, instead of a Dictionary object, you can also use a Collection object, which serves a similar purpose, without the inclusion of an additional runtime library. In fact, the only immediately-obvious difference between this and the VBScript example is dict's data type, and the order that the arguments are passed to the Add method.

<lang vb>Dim dict As New Collection os = Array("Windows", "Linux", "MacOS") owner = Array("Microsoft", "Linus Torvalds", "Apple") For n = 0 To 2

   dict.Add owner(n), os(n)

Next Debug.Print dict.Item("Linux") Debug.Print dict.Item("MacOS") Debug.Print dict.Item("Windows")</lang>