What I'm trying to do is giving a list of columns, get an array of column formats. I have an array of column names, and a has where the key is the column name and the value is the format the column needs. If there's no value in the hash for a given column, it needs to be nil in the resulting array.
Given:
report_columns = ["val1", "val2", "subtotal",
"othertotal", "grand_total", "moar_total"]
column_formats = {"grand_total" => #highlight_money,
"subtotal" => #money}
I can easily do it with this code:
datatype_array = []
report_columns.each {|col| datatype_array << column_formats[col] }
# do stuff with datatype_array
But this is ruby. There's a more concise way to do this! Please let me know what magic method I'm missing.
You're first attempt should be a simple map rather than an each that accumulates onto an array.
datatype_array = report_columns.map { |c| column_formats[c] }
You can also splat the array of columns into Hash#values_at, which expects multiple key names as individual arguments:
datatype_array = column_formats.values_at(*report_columns)
Related
I have an array of hashes:
ary = [{1=>"January", 2=>"February", 3=>"March"}, {11=>"Oct", 12=>"Nov", 13=>"Dec"}]
How can I get the value from a particular hash, based on a key? I would like to do something like:
ary[1].select{|h| h[13]}
to get the value "Dec" from the second hash with the key 13. The above statement returns the whole second hash, which is not the requirement:
{11=>"Oct", 12=>"Nov", 13=>"Dec"}
The select statement will return all the hashes with the key 13.
If you already know which hash has the key then the below code will give u the answer.
ary[1][13]
However if you are not sure which of your hashes in the array has the value, then you could do the following:
values = ary.map{|h| h[13]}.compact
Values will have the value of key 13 from all the hashes which has the key 13.
You can merge the two hashes in one and then query the keys of the merged hash.
c = a.merge(b)
=> {1=>"January", 2=>"February", 3=>"March", 11=>"Oct", 12=>"Nov", 13=>"Dec"}
And then you can do something like:
c[1]
=> "January"
Otherwise, if you want to keep the format as an array of different hashes you can just get the value you want this way:
ary[1][12]
=> "Nov"
But that way you have to always know in which hash inside the array is the element you want, which seems a bit confusing because you could just use different hashes instead of an array of hashes and having to remember each hash's position inside the array.
Firstly make a single hash and then return the value of hash by key.
Make single hash from array with merging elements.
Method 1
hash = ary.reduce({}, :merge)
Method 2
hash = ary.inject(:merge)
Then return the value by key.
hash[13]
I am trying to insert data into Postgres. I have an array of data and I am trying to assign each column a value of the array. Here is an example.
pg_insert = ['12/09/2015', 41, 'test account', '41.0']
Table.create([date: pg_insert[0],
account_number: pg_insert[1],
account_name: pg_insert[2],
values: pg_insert[3]])
Is there a way where I can loop this so I can put i in pg_insert instead of having to type out numbers? I'm not sure how to loop inside of the create() parameter. Is there any way around this?
Any suggestions would be great thanks.
Table.create is accepting a Hash, I'm sure.
So here is what you can do:
Make an Array called keys that contains 4 symbols :date, :account_number, :account_name, and :values.
pg_insert is already an Array.
Now you can put the two Arrays together to make the Hash you need: Hash[keys.zip(pg_insert)]
This allows you to call Table.create like this: Table.create(Hash[keys.zip(pg_insert)])
Here is the finished code then:
keys = [:date, :account_number, :account_name, :values]
pg_insert = ['12/09/2015', 41, 'test account', '41.0']
Table.create(Hash[keys.zip(pg_insert)]) # or Table.create Hash[keys.zip(pg_insert)] if you don't want so many parentheses.
Note that pg_insert will always have to be in the same order as keys.
You can read more about Array#zip and Hash.new to understand how those work. This SO link might also be helpful: Converting an array of keys and an array of values into a hash in Ruby
I have a Hash
person_params = {"firstname"=>"",
"lastname"=>"tom123",
"addresses_attributes"=>
{"0"=>
{"address_type"=>"main",
"catalog_delivery"=>"0",
"street"=>"tomstr",
"city"=>"tomcity"
}
}
}
With person_params[:addresses_attributes], I get:
# => {"0"=>{"address_type"=>"main", "catalog_delivery"=>"0", "street"=>"tomstr", "zip"=>"", "lockbox"=>"", "city"=>"tomcity", "country"=>""}}
1) How can I get a new hash without the leading 0?
desired_hash = {"address_type"=>"main", "catalog_delivery"=>"0", "street"=>"tomstr", "zip"=>"", "lockbox"=>"", "city"=>"tomcity", "country"=>""}
2) How can I check whether the attributes in the new hash are empty?
Answer 1:
person_params[:addresses_attributes]['0']
Answer 2:
hash = person_params[:addresses_attributes]['0']
hash.empty?
This looks just like a params hash from Rails =D. Anyway, it seems that your addresses_attributes contains some nested attributes. This means that what you have in practice is more of an array of hashes than a single hash, and that's what you see right? Instead of it being an actually Ruby Array, it is a hash with the index as a string.
So how do you get the address attributes? Well if you only want to get the first address, here are some ways to do that:
person_params[:addresses_attributes].values.first
# OR
person_params[:addresses_attributes]["0"]
In the first case, we will just take the values from the addreses_attributes hash, which gives us an Array from which we can take the first item. If there are no values in addresses_attributes, then we will get nil.
In the second case, we will just ask for the hash value with the key "0". If there are no values in addresses_attributes, we will get nil with this method also. (You might want to avoid using the second case, if you are not confident that the addresses_attributes hash will always be indexed from "0" and incremented by "1")
I have the following array:
arr = [["Example"]]
I need to reduce it to just "Example" (basically, just remove the array).
I know I could do arr[0][0], but am curious if there's a simple method to just remove the string from the array without using indexes.
For clarification...there will only ever be a single item in the array.
For a single item, you can use:
[['array']].join
=> 'array'
Updated with more examples
If you have multiple items, the strings will be combined:
[['array'], ['array']].join
=> 'arrayarray'
And if you pass a parameter to the join method:
[['array'], ['array']].join('&')
=> 'array&array'
While this is not as efficient as [0][0], it will still work:
arr.flatten.first
Lets say i have an array of arrays, of which i dont know the names, just that they are arrays, and how many of them there are.
bigArray=[smallArrayA[], smallArrayB[]]
Now i can fetch the array(s) by indexposition, like:
smallA = bigArray[0]
smallA << 'input'
But what i'd like to know is the names of the arrays, stored in the 'big' one..
bigArray.inspect
..just gives me:
[['input'],[]]
My problem is that the names of the smaller ones are going to be created dynamiclly, and i need to know their names to modify the right one, later on.
Sounds like you need a hash:
bigHash = { :a => smallArrayA, :b => smallArrayB }
Now you can refer to each element of the hash by name:
bigHash[:a]