x = "one two"
y = x.split
hash = {}
y.each do |key, value|
hash[key] = value
end
print hash
The result of this is: one=> nil, two => nil
I want to make "one" - key, and "two" - value, but how to do this?
It may look like this: "one" => "two"
y is an array, therefore in the block key is the item itself ('one', 'two'), and value is always nil.
You can convert an array to hash using splat operator *
Hash[*y]
A bit faster way of doing it:
x="one two"
Hash[[x.split]]
If you're looking for a more general solution where x could have more elements, consider something like this:
hash = {}
x="one two three four"
x.split.each_slice(2) do |key, value| # each_slice(n) pulls the next n elements from an array
hash[key] = value
end
hash
Or, if you're really feeling fancy, try using inject:
x="one two three four"
x.split.each_slice(2).inject({}) do |memo, (key, value)|
memo[key] = value
memo
end
Related
first_response = [
{"xId" => "123", "yId" => "321"},
{"xId" => "x", "yId" => "y" }
]
first_response.each do |resp|
x_id = resp['xId']
y_id = resp['yId']
puts x_id.to_s
puts y_id.to_s
end
This gives me outputs
123
321
x
y
output hash I want to create is
{123=>{321}, x=>{y}}
first service: I have an array of hash that has two different ids example:(x_id and y_id) (there would be multiple pairs like that in the response)
I want to create a hash that should contain the matching pair of x_id and y_ids that we get from the first service with x_id's as the key for all the pairs.
If you know every hash in first_response is going to contain exactly two key/value pairs, you can extract their values and then convert that result into a hash (see Enumerable#to_h):
first_response.to_h(&:values)
# {"123"=>"321", "x"=>"y"}
Looks like this approach works, but I am not completely sure if that is right
first_response = [{"xId"=>"123","yId"=> "321"}, {"xId"=>"x","yId"=> "y"}]
h = {}.tap do |element|
first_response.each do |resp|
x_id = resp['xId']
y_id = resp['yId']
element[x_id] = y_id
end
end
puts h.to_s
# {"123"=>"321", "x"=>"y"}
I've created the following hash keys with values parsed from PDF into array:
columns = ["Sen", "P-Hire#", "Emp#", "DOH", "Last", "First"]
h = Hash[columns.map.with_index.to_h]
=> {"Sen"=>0, "P-Hire#"=>1, "Emp#"=>2, "DOH"=>3, "Last"=>4, "First"=>5}
Now I want to update the value of each key with 6 equivalent values from another parsed data array:
rows = list.text.scan(/^.+/)
row = rows[0].tr(',', '')
#data = row.split
=> ["2", "6", "239", "05/05/67", "Harp", "Erin"]
I can iterate over #data in the view and it will list each of the 6 values. When I try to do the same in the controller it sets the same value to each key:
data.each do |e|
h.update(h){|key,v1| (e) }
end
=>
{"Sen"=>"Harper", "P-Hire#"=>"Harper", "Emp#"=>"Harper", "DOH"=>"Harper", "Last"=>"Harper", "First"=>"Harper"
So it's setting the value of each key to the last value of the looped array...
I would just do:
h.keys.zip(#data).to_h
If the only purpose of h is as an interim step getting to the result, you can dispense with it and do:
columns.zip(#data).to_h
There are several ways to solve this problem but a more direct and straight forward way would be:
columns = ["Sen", "P-Hire#", "Emp#", "DOH", "Last", "First"]
...
#data = row.split
h = Hash.new
columns.each_with_index do |column, index|
h[column] = #data[index]
end
Another way:
h.each do |key, index|
h[key] = #data[index]
end
Like I said, there are several ways of solving the issue and the best is always going to depend on what you're trying to achieve.
I am trying to remove the elements in an array from a hash and the array forms part of the 'keys' in a hash. Here is an illustration.
hash = {'a' = 1, 'b' = 2, 'c' =3, 'd' = 4}
arr = ["a","d"] #Now I need to remove the elements from this array from the above hash
Resultant hash should be as below
new_hash = {'b' = 2,'c' =3}
This is what I tried unfortunately it doesn't seem to work
for i in 0..hash.length-1
arr.each do |key_to_del|
hash.delete key_to_del unless h.nil?
end
end
Your hash isn't correct format. It should be like this.
hash={"a"=>1, "b"=>2, "c"=>3, "d"=>4}
arr=["a","d"]
Solution 1
hash.reject! {|k, v| arr.include? k }
Solution 2
arr.each{|v| hash.delete(v)}
I have a hash with some key value pairs as below:
#level2 = #l2.inject(Hash.new(0)) { |hash,element|
hash[element] +=1
hash }
I perform some sorting on the hash based on the keys.
#level2 = #level2.sort_by { |x, _| x }.reverse
Now I assume that the sort_by gives me an Array of Arrays. I want to split this into 2 arrays such that my first array should contain all keys and second array should contain all values.
The hash#keys and hash#values are not accessible after sorting the hash. So that does not work in this case.
Regardless of how you make the hash it will will have a Hash#keys method and a Hash#values. They both return arrays that are just what you seem to want.
keys_array = #level2.keys
values_array = #level2.values
You could iterate over the array of arrays and add each element to a new array. This would keep the order of the elements.
keys_array = []
values_array = []
#level2.each do |key, value|
keys_array << key
values_array << value
end
I'm passing the below information through parameter from view to controller
parameters:{"Something"=>{"a" => "1", "b" => "0", "c" => "1", "d" => "0" #and so on}}
I want to access all the characters that have "1" as their value and concatenate into the string.
I tried
Something.each do |key, value|
if(value == "1")
string = string + key
end
end
It is throwing error saying that it could not execute nil.each and that i might be expecting an array.
It appears to me that Something is a hash and in turn has some hashes in it.
So i initialised Something to
Something = Hash.new { |Something, k| Something[k] = Hash.new }
But i still get the same error.
Just work with the params hash. This should do what you need:
params["Something"].select {|k, v| v == "1"}.keys.reduce(:+)
select filters the params to only those with the value "1"
keys returns an array with all the keys in the hash
reduce joins all elements with a concat operation (+)
Edit
To concatenate and add the "Extra" word:
For each parameter:
params["Something"].select {|k, v| v == "1"}.keys.inject("") {|result, p| result += "Extra #{p}"}
Only to the extra parameters, but not to the first one:
params["Something"].select {|k, v| v == "1"}.keys.inject {|result, p| result += "Extra #{p}"}
See more information on inject here.