Hash from two arrays: Difference between revisions
(Undo revision 7371 by Special:Contributions/RrsVbp (User talk:RrsVbp)) |
|||
Line 2: | Line 2: | ||
Using two Arrays of equal length, create a Hash object where the elements from on array (the keys) are linked to the elements of the other (the values) |
Using two Arrays of equal length, create a Hash object where the elements from on array (the keys) are linked to the elements of the other (the values) |
||
==[[Ada]]== |
|||
[[Category:Ada]] |
|||
Compiler: GNAT 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; |
|||
==[[C plus plus|C++]]== |
==[[C plus plus|C++]]== |
Revision as of 19:44, 25 August 2007
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 on array (the keys) are linked to the elements of the other (the values)
Ada
Compiler: GNAT 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;
C++
By strict definition a std::map is not a hash, but it provides the same functionality (but note that some C++ has hash sets too).
Compiler: g++ 4.0.2
#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>); }
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]; }
D
char[][] keys = ["one", "two", "three"] int[] values = [1, 2, 3]; int[char[]] hash; foreach(i,k; keys) hash[k] = values[i];
E
def keys := ["one", "two", "three"] def values := [1, 2, 3] __makeMap.fromColumns(keys, values)
Haskell
Interpreter: GHCi 6.6
import Data.Map makeMap ks vs = fromList $ zip ks vs mymap = makeMap ['a','b','c'] [1,2,3]
JavaScript
var keys = ['a', 'b', 'c']; var values = [1, 2, 3]; var map = {}; for(var i in keys) { map[ keys[i] ] = values[i]; }
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:
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.
Perl
Interpreter: Perl 5
use List::MoreUtils qw(zip); my @keys = qw(a b c); my @vals = (1, 2, 3); my %hash = zip @keys, @vals;
Using no modules:
my %hash; @hash{qw(a b c)} = (1, 2, 3);
PHP
PHP 5:
$keys = array('a', 'b', 'c'); $values = array(1, 2, 3); $hash = array_combine($keys, $values);
PHP 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]; }
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;
Python
Interpreter: Python 2.5
keys = ['a', 'b', 'c'] values = [1, 2, 3] hash = dict(zip(keys, values)) # Lazily: from itertools import izip hash = dict(izip(keys, values))
Ruby
keys=['hal',666,[1,2,3]] vals=['ibm','devil',123] hash = Hash[*keys.zip(vals).flatten] # now 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
Scala
val keys = Array(1, 2, 3) val values = Array("A", "B", "C") val map = Map(keys.zip(values) : _*) // returns Map(1 -> "A", 2 -> "B", 3 -> "C") // keys.zip(values) is an array of pairs : Array({1, "A"}, {2, "B"}, {3, "C"}) // Map(...) expects multiple pairs arguments. Syntax ": _*" tells the single argument contains multiple values.
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 }