Does julia have hashmaps like structures? - data-structures

I am new to julia!I have just switched from java to julia, Can somebody tell me does julia have hashmap like structures? if No, then how do I map one type to another type in julia?

Yes!! It does have. Below is how you can create and access one inside Julia.
# Creating the Dict in Julia
julia> hashmap = Dict("language"=>"julia","version"=>"0.6")
Dict{String,String} with 2 entries:
"language" => "julia"
"version" => "0.6"
# To access individual keys
julia> hashmap["language"]
"julia"
# To find the fields inside a dictionary
julia> fieldnames(hashmap)
8-element Array{Symbol,1}:
:slots
:keys
:vals
:ndel
:count
:age
:idxfloor
:maxprobe
# To iterate over the hashmap
julia> for i in hashmap
println(i)
end
"language"=>"julia"
"version"=>"0.6"

The Julia Dict is implemented as a hashmap. As with Java, it is important to consider the interface versus the implementation.
Associative is an abstract type that roughly corresponds to Map in Java; these objects can be indexed by their keys to get the corresponding values:
value = associative[key]
Dict is a concrete subtype of Associative that is implemented as an unordered hashmap.
dict = Dict("a" => 1, "b" => 3)
#show dict["a"] # dict["a"] = 1

Related

Convert array of hashes to single hash with values as keys

Given a source array of hashes:
[{:country=>'england', :cost=>12.34}, {:country=>'scotland', :cost=>56.78}]
Is there a neat Ruby one-liner for converting it to a single hash, where the values for the :country key in the original hash (guaranteed to be unique) become keys in the new hash?
{:england=>12.34, :scotland=>56.78}
This should do what you want
countries.each_with_object({}) { |country, h| h[country[:country].to_sym] = country[:cost] }
=> {:england=>12.34, :scotland=>56.78}
You can do that using Enumerable#inject:
countries.inject({}) { |hsh, element| hsh.merge!(element[:country].to_sym => element[:cost]) }
=> {:england=>12.34, :scotland=>56.78}
We initialise the accumulator as {}, and then we iterate over each of the elements of the initial array and add the new formatted element to the accumulator.
One point to add is that using hsh.merge or hsh.merge! would have the same effect for the output, given that inject will set the accumulator hsh as the return value from the block. However, using merge! is better when it comes to memory usage, given that merge will always generate a new Hash, whereas merge! will apply the merge over the same existing Hash.
One more possible solution is:
countries.map(&:values).to_h
=> {"england"=>12.34, "scotland"=>56.78}

How to get the index of a key in a hash?

I'm trying to get the index of a key in a hash.
I know how to do this in an array:
arr = ['Done', 13, 0.4, true]
a = arr.index('Done')
puts a
Is there a method or some sort of way to do this something like this with a key in a hash? Thanks!
Hashes aren't usually treated as ordered structures, they simply have a list of keys and values corresponding to those keys.
It's true that in Ruby hashes are technically ordered, but there's very rarely an actual use case for treating them as such.
If what you want to do is find the key corresponding to a value in a hash, you can simply use the Hash#key method:
hash = { a: 1, b: 2 }
hash.key(1) # => :a
I suppose you could use hash.keys.index(hash.key(1)) to get 0 since it's the first value, but again, I wouldn't advise doing this because it's not typical use of the data structure
There are at least a couple ways you can get this information, the 2 that come to mind are Enumerable's find_index method to pass each element to a block and check for your key:
hash.find_index { |key, _| key == 'Done' }
or you could get all the keys from your hash as an array and then look up the index as you've been doing:
hash.keys.index('Done')

Reference to array cell in Ruby?

Can I have a reference to an array cell in Ruby? In C++, I can do something like:
int& ref = arr[x][y];
and later work with the variable ref without the need of typing the whole arr[x][y].
I want to do this as I need to access one and the same cell multiple times throughout a function (I'm doing memoization) and typing unnecessary indexes may only lead to errors.
All values in ruby are references, so this is certainly possible, but with some important limitations. One caveat is that ruby doesn't DIRECTLY support multidimensional arrays, but you can implement one as an array of arrays or as a hash keyed by tuples.
You can achieve this in cases where the value at (x, y) has already been set by assigning to the value at the given coordinates. If no value currently exists at that location, then you must initialize that value before you can have a reference to it:
# if x and y are indices and a is your "multidimensional array"
a[x][y] = 'First Value' # Initial value at (x, y)
ref = a[x][y] # take a reference to the value referenced by a[x][y]
ref.gsub! 'First', 'Second'
a[x][y] # => 'Second Value'
Keep in mind that the assignment operator in ruby generally means "make the reference on the left side refer to the value on the right". This means that if you use the assignment operator on your reference, then you're actually making it refer to a new value:
a[x][y] = 1 # Initialize value with 1
ref = a[x][y] # Take the reference
ref += 1 # Assignment
ref # => 2
a[x][y] # => 1
You might have better success by using a Hash and keying the hash with tuples of your coordinates, and then using these tuples to get references to specific locations:
a = {}
loc = [x, y]
a[loc] = 'First Value' # Initial value
a[[x,y]] # => 'First Value'
a[loc] = 'Second Value' # Assignment
a[[x,y]] # => 'Second Value'
a[loc] = 1 # Assignment
a[loc] += 1 # Assignment
a[[x,y]] # => '2'
Ruby is considered pass by value so to answer your question (not pass by reference like C++), it's not directly possible to do what you're asking.
There's a really good post in this answer by Abe that you should read through:
Is Ruby pass by reference or by value?
For ref to continue to point to the actual data of arr[x][y] at any given time, one possibiliy is to write it as a method :
def ref
ar[1][1]
end
In a high level language like ruby, all variables are references and there is no "pointers" or levels of indirections like C or C++, you should create objects to hold this references to get similar behavior
This is what I would do on ruby
Suppose you need to save a "pointer" to a ruby array, then you create a Class to access the array in a given index (there is no such thing like getting a "pointer" to a value in ruby)
class ArrayPointer
def initialize(array, index)
#array = array
#index = index
end
def read
#array[index]
end
def write(value)
#array[index] = value
end
end
Then, you use the clase this way
array = [1, 2, 3]
pointer = ArrayPointer.new(array, 1)
pointer.write(20)
puts array # [1, 20, 3]
You also can get "pointers" to local variables, but is too weird and uncommon in ruby world and it almost doesn't make sense
Note this kind of code is weird and not common in ruby, but it is interesting from the didactic point of view to compare two great languages like Ruby and C
In the Object Oriented nature of ruby, is preferable to design good abstractions (e.g. instead of using an array to represent your data, if preferable to define a class with methods like the ruby way) before only using elemental structures such as Array or Hash to represent the data used by your program (the last approach common in C, is not the ruby way)

How to save an array of information coming from a hash in Ruby

I am new to ruby and don't have much experience with hashes, I have a variable named tweets and it is a hash as such:
{"statuses"=>[{"metadata"=>{"result_type"=>"recent", "iso_language_code"=>"tl"}, "lang"=>"tl"}]}
I would like to save the array of information as a separate variable in an array. How would I go about this?
Hash's have 2 very nice methods,
hash.values
hash.keys
in your case -
h = {"statuses"=>[{"metadata"=>{"result_type"=>"recent", "iso_language_code"=>"tl"}, "lang"=>"tl"}]}
p h.values
p.keys
These output arrays of each type. This might be what you want.
Also, this question will very well be closed. 1 Google search reported several Hash to Array SO questions.
Ruby Hash to array of values
Converting Ruby hashes to arrays
If you have a Hash like so:
hash = {:numbers => [1,2,3,4]}
And you need to capture the array into a new variable. You can just access the key and assign it to a new variable like so:
one_to_five = hash[:numbers]
However, note that the new variable actually holds the array that is in the hash. So altering the hash's array alters the new variable's array.
hash[:numbers] << 6
puts one_to_five #=> [1,2,3,4,5,6]
If you use dup, it will create a copy of the array so it will be two separate arrays.
one_to_five = hash[:numbers].dup
hash[:numbers] << 6
puts one_to_five #=> [1,2,3,4,5]
So, in your case:
hash = {'statuses' => [{"metadata"=>{"result_type"=>"recent", "iso_language_code"=>"tl"}, "lang"=>"tl"}]}
new_array = hash['statuses'].dup
However, it would be interesting to see what it is you are wishing to accomplish with your code, or at least get a little more context, because this may not be the best approach for your final goal. There are a great many things you can do with Arrays and Hashes (and Enumerable) and I would encourage you to read through the documentation on them.

Why does hash.keys.class return Arrays?

New to Ruby, I'm just missing something basic here. Are the keys in a Hash considered an Array unto themselves?
Yes, Hash#keys returns the hash's keys as a new array, i.e., the hash and the array returned by Hash#keys are completely independent of each other:
a = {}
b = a.keys
c = a.keys
b << :foo
a # still {}
b # [:foo]
c # still []
a[:bar] = :baz
a # {:bar => :baz}
b # still [:foo]
c # still []
From the documentation of hash.keys:
Returns a new array populated with the keys from this hash. See also Hash#values.
So the class is Array because the return value is an array.
About your question "Are the keys in a Hash considered an Array unto themselves?", they "kind" of are, hashes in Ruby are implemented as struct (st_table) which contains a list of pointers to each of its entries(st_table_entry),the st_table_entry contains the key and its value, so I guess what the keys method does is just transversing that list taking out each of the keys.
You can read this article of Ilya Grigorik where he explains much better Hashes in Ruby http://www.igvita.com/2009/02/04/ruby-19-internals-ordered-hash/
Do you think there's something paradoxical about this? Keep in mind that hashes aren't arrays in Ruby.

Resources