Hash from two arrays

From Rosetta Code
Jump to: navigation, search
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)

Related task: Associative arrays/Creation

Contents

[edit] 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];
}
}
}

[edit] Ada

Works with: GNAT version GPL 2007
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;

[edit] Argile

Works with: Argile version 1.1.0
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

[edit] 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"]

[edit] AWK

Awk arrays are used for both lists and hash maps.

$ 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

[edit] BASIC256

Solution is at Associative_array/Creation#BASIC256.

[edit] BBC BASIC

      DIM array1$(4) : array1$() = "0", "1", "2", "3", "4"
DIM array2$(4) : array2$() = "zero", "one", "two", "three", "four"
 
FOR index% = 0 TO DIM(array1$(),1)
PROCputdict(mydict$, array2$(index%), array1$(index%))
NEXT
PRINT FNgetdict(mydict$, "3")
END
 
DEF PROCputdict(RETURN dict$, value$, key$)
IF dict$ = "" dict$ = CHR$(0)
dict$ += key$ + CHR$(1) + value$ + CHR$(0)
ENDPROC
 
DEF FNgetdict(dict$, key$)
LOCAL I%, J%
I% = INSTR(dict$, CHR$(0) + key$ + CHR$(1))
IF I% = 0 THEN = "" ELSE I% += LEN(key$) + 2
J% = INSTR(dict$, CHR$(0), I%)
= MID$(dict$, I%, J% - I%)

[edit] 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
& ;
 

Output:

apple.fruit
three.3
two.2

[edit] 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]

[edit] 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.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#define KeyType const char *
#define ValType int
 
#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;
}

[edit] 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.

#include <map>
#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] ;
}
}

Alternatively:

#include <map>       // for std::map
#include <algorithm> // for std::transform
#include <string> // for std::string
#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>);
}

[edit] C#

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] );
}

Alternate way of adding values

for( int i = 0; i < arg_length; i++ ){
h[ arg_keys[i] ] = arg_values[i];
}

[edit] Clojure

(zipmap [\a \b \c] [1 2 3])

[edit] Coco

keys = <[apple banana orange grape]>
values = <[red yellow orange purple]>
 
object = new
@[keys[i]] = values[i] for i til keys.length

[edit] CoffeeScript

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

[edit] 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>

[edit] Common 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))

Or, using cl:loop:

(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)))

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

[edit] D

void main() {
import std.array, std.range;
 
immutable hash = ["a", "b", "c"].zip([1, 2, 3]).assocArray;
}

[edit] Déjà Vu

local :h_keys [ :one :two :three ]
local :h_values [ 1 2 3 ]
local :h {}
for item in h_keys:
set-to h item pop-from h_values
 

[edit] E

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

[edit] Erlang

 
Dictionary = dict:from_list( lists:zip([key1, key2, key3], [value1, 2, 3]) ).
 

[edit] F#

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

[edit] Factor

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

[edit] Falcon

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

[edit] 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])
}
}
}
 

[edit] Frink

There is a built-in dictionary/hash constructor that takes two arrays as input.

 
a = new dict[["a", "b", "c"], [1, 2, 3]]
 

[edit] Go

package main
 
import "fmt"
 
func main() {
keys := []string{"a", "b", "c"}
vals := []int{1, 2, 3}
hash := map[string]int{}
for i, key := range keys {
hash[key] = vals[i]
}
fmt.Println(hash)
}
Output:
map[b:2 a:1 c:3]

[edit] Groovy

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

Alternative Version:

List.metaClass.hash = { list -> [delegate, list].transpose().collectEntries { [(it[0]): it[1]] } }

Test:

assert (['a', 'b', 'c'].hash(['aaa', 'bbb', 'ccc'])) == [a: 'aaa', b: 'bbb', c: 'ccc']

[edit] Harbour

LOCAL arr1 := { 6, "eight" }, arr2 := { 16, 8 }
LOCAL hash := { => }
LOCAL i, j
 
FOR EACH i, j IN arr1, arr2
hash[ i ] := j
NEXT

[edit] Haskell

Works with: GHCi version 6.6
import Data.Map
 
makeMap ks vs = fromList $ zip ks vs
mymap = makeMap ['a','b','c'] [1,2,3]

[edit] Icon and Unicon

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

[edit] Ioke

{} addKeysAndValues([:a, :b, :c], [1, 2, 3])

[edit] J

Solution:

hash=: vals {~ keys&i.

For example:

   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

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.

[edit] 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]);
}
}

[edit] JavaScript

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

[edit] jq

jq only supports hashing of strings. In the following, accordingly, we assume that one array (keys) is an array of strings.

# hash(keys) creates a JSON object with the given keys as keys
# and values taken from the input array in turn.
# "keys" must be an array of strings.
# The input array may be of any length and have values of any type,
# but only the first (keys|length) values will be used;
# the input will in effect be padded with nulls if required.
def hash(keys):
. as $values
| reduce range(0; keys|length) as $i
( {}; . + { (keys[$i]) : $values[$i] });
 
[1,2,3] | hash( ["a","b","c"] )
Output:
jq -n -f Hash_from_two_arrays.jq
{
"a": 1,
"b": 2,
"c": 3
}

To hash an array of distinct integers, the tostring filter can be used, e.g.

[10,20,30] | hash( [1,2,3] | map(tostring) )
yields:
{
"1": 10,
"2": 20,
"3": 30
}

[edit] Julia

Translation of: Python

Using a dictionary comprehension:

julia> K = ["a", "b", "c"]
julia> V = [1, 2, 3]
julia> H = [key => value for (key, value) in zip(K,V)]
{"b"=>2,"c"=>3,"a"=>1}
The comprehension can also be typed, in order to restrict the dictionary to certain key/value types:
julia> H = (String=>Int)[key => value for (key, value) in zip(K,V)]
["b"=>2,"c"=>3,"a"=>1]

Using a dictionary constructor function (Dict):

julia> H = Dict(K, V)
["b"=>2,"c"=>3,"a"=>1]

[edit] K

The keys in a dictionary must be a symbol.

   a: `zero `one `two  / symbols
b: 0 1 2
 
d:. a,'b / create the dictionary
.((`zero;0;)
(`one;1;)
(`two;2;))
 
d[`one]
1

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

   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"


[edit] Lasso

local(
array1 = array('a', 'b', 'c'),
array2 = array(1, 2, 3),
hash = map
)
 
loop(#array1 -> size) => {
#hash -> insert(#array1 -> get(loop_count) = #array2 -> get(loop_count))
}
 
#hash

-> map(a = 1, b = 2, c = 3)

[edit] Lang5

: >table  2 compress -1 transpose ;
['one 'two 'three 'four] [1 2 3 4] >table

[edit] LFE

(let* ((keys (list 'foo 'bar 'baz))
(vals (list '"foo data" '"bar data" '"baz data"))
(tuples (: lists zipwith
(lambda (a b) (tuple a b)) keys vals))
(my-dict (: dict from_list tuples)))
(: io format '"fetched data: ~p~n" (list (: dict fetch 'baz my-dict))))
 

[edit] Lua

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

[edit] Maple

 
A := [1, 2, 3];
B := ["one", "two", three"];
T := table( zip( `=`, A, B ) );
 

[edit] Mathematica

Map[(Hash[Part[#, 1]] = Part[#, 2]) &,
Transpose[{{1, 2, 3}, {"one", "two", "three"}}]]
 
?? Hash
->Hash[1]=one
->Hash[2]=two
->Hash[3]=three

[edit] MATLAB / Octave

See Associative arrays/Creation for clarification of limitations and differences between the two methods.

[edit] MATLAB/Octave: structs

function s = StructFromArrays(allKeys, allVals)
% allKeys must be cell array of strings of valid field-names
% allVals can be cell array or array of numbers
% Assumes arrays are same size and valid types
s = struct;
if iscell(allVals)
for k = 1:length(allKeys)
s.(allKeys{k}) = allVals{k};
end
else
for k = 1:length(allKeys)
s.(allKeys{k}) = allVals(k);
end
end
end
Output:
>> ages = StructFromArrays({'Joe' 'Bob' 'Sue'}, [21 35 27])

ages = 

    Joe: 21
    Bob: 35
    Sue: 27

[edit] MATLAB only: containers.Map

containers.Map constructor provides this functionality already.

>> ages = containers.Map({'Joe' 'Bob' 'Sue'}, [21 35 27]);
>> keys(ages)

ans = 

    'Bob'    'Joe'    'Sue'

>> values(ages)

ans = 

    [35]    [21]    [27]

[edit] NetRexx

[edit] REXX Style

Translation of: REXX
/* NetRexx program ****************************************************
* 04.11.2012 Walter Pachl derived from REXX
**********************************************************************/

options replace format comments java crossref savelog symbols nobinary
values='triangle quadrilateral pentagon hexagon heptagon octagon' -
'nonagon decagon dodecagon'
keys ='three four five six seven eight nine ten twelve'
kcopy=keys
k='' /* initialize the arrays */
v=''
value='unknown'
Loop i=1 By 1 While kcopy>'' /* initialize the two arrays */
Parse kcopy ki kcopy; k[i]=ki
Parse values vi values; v[i]=vi
End
Loop j=1 To i-1
value[k[j]]=v[j]
End
Say 'Enter one of these words:'
Say ' 'keys
Parse Ask z
Say z '->' value[z]

[edit] Java Collections

NetRexx has access to Java's Collection objects too.

/* NetRexx */
options replace format comments java crossref symbols nobinary
 
vals = [ 'zero', 'one', 'two', 'three', 'four', 'five' ]
keys = [ 'k0', 'k1', 'k2', 'k3', 'k4', 'k5' ]
hash1 = Rexx
hash2 = Map
 
hash1 = HashMap()
hash2 = ''
makeHash(hash1, keys, vals) -- using a Map object (overloaded method)
makeHash(hash2, keys, vals) -- using a Rexx object (overloaded method)
 
return
 
-- Using a Java collection object
method makeHash(hash = Map, keys = Rexx[], vals = Rexx[]) static
loop k_ = 0 to keys.length - 1
hash.put(keys[k_], vals[k_])
end k_
 
key = Rexx
loop key over hash.keySet()
say key.right(8)':' hash.get(key)
end key
say
 
return
 
-- For good measure a version using the default Rexx object as a hash (associative array)
method makeHash(hash = Rexx, keys = Rexx[], vals = Rexx[]) static
loop k_ = 0 to keys.length - 1
hash[keys[k_]] = vals[k_]
end k_
 
loop key over hash
say key.right(8)':' hash[key]
end key
say
 
return
 

[edit] 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);
}
}

[edit] Nimrod

import tables, sequtils
 
proc asKeyVal(x): auto = cast[seq[tuple[key: char, val: int]]](x)
 
let keys = @['a','b','c']
let values = @[1, 2, 3]
 
let table = toTable zip(keys, values).asKeyVal

[edit] 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));
};
}
}
}
 

[edit] Objective-C

NSArray *keys = @[@"a", @"b", @"c"];
NSArray *values = @[@1, @2, @3];
NSDictionary *dict = [NSDictionary dictionaryWithObjects:values forKeys:keys];

[edit] OCaml

The idiomatic solution uses lists rather than arrays.

let keys = [ "foo"; "bar"; "baz" ]
and vals = [ 16384; 32768; 65536 ]
and hash = Hashtbl.create 0;;
 
List.iter2 (Hashtbl.add hash) keys vals;;

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)

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;;

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:

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;;

[edit] ooRexx

 
array1 = .array~of("Rick", "Mike", "David")
array2 = .array~of("555-9862", "555-5309", "555-6666")
 
-- if the index items are constrained to string objects, this can
-- be a directory too.
hash = .table~new
 
loop i = 1 to array1~size
hash[array1[i]] = array2[i]
end
 

[edit] 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]}}

[edit] Pascal

Works with: Free_Pascal
Library: contnrs
program HashFromTwoArrays (Output);
 
uses
contnrs;
 
var
keys: array[1..3] of string = ('a', 'b', 'c');
values: array[1..3] of integer = ( 1, 2, 3 );
hash: TFPDataHashTable;
i: integer;
 
begin
hash := TFPDataHashTable.Create;
for i := low(keys) to high(keys) do
hash.add(keys[i], @values[i]);
writeln ('Length of hash table: ', hash.Count);
hash.Destroy;
end.

Output:

% ./HashFromTwoArrays
Length of hash table: 3

[edit] Perl

my @keys = qw(a b c);
my @vals = (1, 2, 3);
my %hash;
@hash{@keys} = @vals;
Alternatively, using :
use List::MoreUtils qw(zip);
my %hash = zip @keys, @vals;

[edit] Perl 6

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

or just

my @v = <a b c d e>;
my %hash = @v Z @v.keys;


Alternatively:

my %hash;
%hash{@keys} = @vals;

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

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

All of these zip forms trim the result to the length of the shorter of their two input lists. If you wish to enforce equal lengths, you can use a strict hyperoperator instead:

{ @keys »=>« @values }

This will fail if the lists differ in length.

[edit] PHP

Works with: PHP version 5
$keys = array('a', 'b', 'c');
$values = array(1, 2, 3);
$hash = array_combine($keys, $values);
Works with: PHP version 4
$keys = array('a', 'b', 'c');
$values = array(1, 2, 3);
$hash = array();
for ($idx = 0; $idx < count($keys); $idx++) {
$hash[$keys[$idx]] = $values[$idx];
}

[edit] PicoLisp

(let (Keys '(one two three)  Values (1 2 3))
(mapc println
(mapcar cons Keys Values) ) )

Output:

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

[edit] 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;

[edit] PostScript

Library: initlib
 
% 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
 

[edit] 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
}

[edit] 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).

[edit] 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

[edit] Python

Works with: Python version 3.0+ and 2.7

Shows off the dict comprehensions in Python 3 (that were back-ported to 2.7):

keys = ['a', 'b', 'c']
values = [1, 2, 3]
hash = {key: value for key, value in zip(keys, values)}
Works with: Python version 2.2+
keys = ['a', 'b', 'c']
values = [1, 2, 3]
hash = dict(zip(keys, values))
 
# Lazily, Python 2.3+, not 3.x:
from itertools import izip
hash = dict(izip(keys, values))
Works with: Python version 2.0+
keys = ['a', 'b', 'c']
values = [1, 2, 3]
hash = {}
for k,v in zip(keys, values):
hash[k] = v

The original (Ruby) example uses a range of different types as keys. Here is similar in python (run at the shell):

>>> 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

[edit] 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.

# 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
# Get value corresponding to a key
values["Sam Doe"] # vals["Sam Doe"]
# Get all keys corresponding to a value
names(values)[values==152] # "John Smith" "Sandra Dee"

[edit] Racket

 
(make-hash (map cons '("a" "b" "c" "d") '(1 2 3 4)))

Alternatively:

 
(define (connect keys vals) (for/hash ([k keys] [v vals]) (values k v)))
;; Example:
(connect #("a" "b" "c" "d") #(1 2 3 4))
 

[edit] Raven

[ 'a' 'b' 'c' ] as $keys [ 1 2 3 ] as $vals
$keys $vals combine as $hash

[edit] REXX

/*REXX program demonstrate  hashing  of a  stemmed array  (from a key). */
/*names of the 9 regular polygons*/
values='triangle quadrilateral pentagon hexagon heptagon octagon nonagon decagon dodecagon'
keys ='thuhree vour phive sicks zeaven ate nein den duzun'
 
/*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*/
pad=left('',30) /*used for padding the display. */
say 'key:' query pad "value:" hash.query /*show & tell some stuff.*/
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────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 /*j*/
return

output when using the input of: phive

key: phive                                value: pentagon

[edit] Ruby

 
keys = ['hal',666,[1,2,3]]
vals = ['ibm','devil',123]
 
hash = Hash[keys.zip(vals)]
 
p hash # => {"hal"=>"ibm", 666=>"devil", [1, 2, 3]=>123}
 
#retrieve the value linked to the key [1,2,3]
puts hash[ [1,2,3] ] # => 123
 

Or define a new method in class Array:

 
class Array
def zip_hash(other)
Hash[self.zip(other)]
end
end
 
hash = %w{ a b c }.zip_hash( %w{ 1 2 3 } )
p hash # => {"a"=>"1", "b"=>"2", "c"=>"3"}
 

Hash[] is calling "to_hash" inside. Therefore, it doesn't work out when making a method name "to_hash".

In Ruby 2.1 the method "to_h" was introduced:

keys = ['hal', 666, [1,2,3]]
vals = ['ibm', 'devil', 123]
 
keys.zip(vals).to_h

[edit] 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;

[edit] Scala

val keys = List(1, 2, 3)
val values = Array("A", "B", "C") // Array mixed with List
val map = keys.zip(values).toMap // and other Seq are possible.
 
// Testing
assert(map == Map(1 ->"A", 2 -> "B", 3 -> "C"))
println("Successfully completed without errors.")

[edit] Scheme

Using SRFI 69:

(define (lists->hash-table keys values . rest)
(apply alist->hash-table (map cons keys values) rest))

[edit] 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;

[edit] Sidef

var keys = %w(a b c);
var vals = [1, 2, 3];
 
var hash = Hash.new;
hash[keys] = vals;

[edit] Smalltalk

Works with: GNU 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.
Works with: Smalltalk/X
Dictionary 
withKeys:#('one' 'two' 'three')
andValues:#('eins' 'zwei' 'drei')
Works with: Smalltalk/X
Dictionary withAssociations:{ 'one'->1 . 'two'->2 . 'three'->3 }

[edit] SNOBOL4

Works with: Macro Spitbol
Works with: Snobol4+
Works with: CSnobol
*       # Fill arrays
keys = array(5); vals = array(5)
ks = 'ABCDE'; vs = '12345'
kloop i = i + 1; ks len(1) . keys<i> = :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

Output:

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

[edit] Sparkling

let keys = { "foo", "bar", "baz" };
let vals = { 13, 37, 42 };
var hash = {};
for var i = 0; i < sizeof keys; i++ {
hash[keys[i]] = vals[i];
}

[edit] Standard ML

Works with: SML/NJ

Using functional binary search trees instead of hash tables:

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));
Works with: SML/NJ

Using hash tables:

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);

[edit] Swift

let keys = ["a","b","c"]
let vals = [1,2,3]
var hash = [String: Int]()
for (key, val) in Zip2(keys, vals) {
hash[key] = val
}

[edit] 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:

set keys [list fred bob joe]
set values [list barber plumber tailor]
array set arr {}
foreach a $keys b $values { set arr($a) $b }

Alternatively, a dictionary could be used:

foreach a $keys b $values {
dict set jobs $a $b
}

[edit] TXR

[edit] One-liner, using quasiquoted hash syntax

$ txr -p  '^#H(() ,*[zip #(a b c) #(1 2 3)])))'
#H(() (c 3) (b 2) (a 1))

[edit] One-liner, using hash-construct function

$ txr -p  '(hash-construct nil [zip #(a b c) #(1 2 3)])))'
#H(() (c 3) (b 2) (a 1))

[edit] Explicit construction and stuffing

@(do
(defun hash-from-two (vec1 vec2 . hash-args)
(let ((table (hash . hash-args)))
(mapcar (do sethash table) vec1 vec2)
table))
 
(prinl (hash-from-two #(a b c) #(1 2 3))))
$ ./txr hash-from-two.txr 
#H(() (c 3) (b 2) (a 1))

[edit] UnixPipes

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

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)

[edit] UNIX Shell

Works with: Bash version 4
keys=( foo bar baz )
values=( 123 456 789 )
declare -A hash
 
for (( i = 0; i < ${#keys[@]}; i++ )); do
hash["${keys[i]}"]=${values[i]}
done
 
for key in "${!hash[@]}"; do
printf "%s => %s\n" "$key" "${hash[$key]}"
done
Output:
bar => 456
baz => 789
foo => 123

[edit] Ursala

There's a built in operator for this.

keys   = <'foo','bar','baz'>
values = <12354,145430,76748>
 
hash_function = keys-$values

test program:

#cast %nL
 
test = hash_function* <'bar','baz','foo','bar'>

output:

<145430,76748,12354,145430>

[edit] Vala

Library: Gee
 
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];
}
}
}
 

[edit] VBScript

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

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")

Output (in message boxes):

Linus Torvalds
Apple
Microsoft

[edit] 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.

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")

[edit] Wortel

Wortel has an inbuilt operator to do this: @hash.

@hash ["a" "b" "c"] [1 2 3] ; returns {a 1 b 2 c 3}

This function can also be defined as:

^(@obj @zip)

Example:

@let {
hash ^(@obj @zip)
 !!hash ["a" "b" "c"] [1 2 3]
}

Returns

{a 1 b 2 c 3}

[edit] zkl

keys:=T("a","b","c","d"); vals:=T(1,2,3,4);
d:=Utils.zipWith(Void,keys,vals).toDictionary();
d.println();
d["b"].println()
Output:
D(a:1,b:2,c:3,d:4)
2
Personal tools
Namespaces

Variants
Actions
Community
Explore
Misc
Toolbox