How to add string into Hash with each - ruby-on-rails

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

Ruby creating a new hash from an array of key, value

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

Updating Ruby Hash Values with Array Values

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.

Remove specific key set which is an array from a hash

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

Split an Array of arrays into 2 separate arrays in Ruby

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

Hashes in hashes ruby on rails

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.

Resources