How to check if nested hash attributes are empty - 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")

Related

How to sort an array in Ruby

Persoane = []
Nume = gets
Persoane.push Nume.split(",")
puts Persoane.sort
I am trying to get an user to input carachters that get split into substrings which get inserted in an array, then the program would output the strings in alphabetical order. It doesnt seem to work and I just get the array's contents, like so:
PS C:\Users\Lenovo\Desktop\Ruby> ruby "c:\Users\Lenovo\Desktop\Ruby\ruby-test.rb"
Scrie numele la persoane
Andrei,Codrin,Bradea
Andrei
Codrin
Bradea
PS C:\Users\Lenovo\Desktop\Ruby>
you can do this :
Nume = gets
puts Nume.split(",").sort
or in 1 line
array = gets.chomp.split(",").sort
The error is because of your use of push. Let's assume that you define the constant Nume by
Nume='Andrei,Codrin,Bradea'
Then, Nume.split(',') would return the Array ['Andrei', 'Codrin', 'Bradea']. When you do a Persoane.push, the whole array is added to your array Persoane as a single element. Therefore, Persoane contains only one Element, as you can verify when you do a
p Persoane
If you sort a one-element array, the result will also be just that one element - there is nothing to sort.
What you can do is using concat instead of push. This would result in Persoane being a 3-element array which can be sorted.
I'm not sure you need use constants here
If you don't need keep user input and use it somewhere, you can just chain methods like this
persons = gets.chomp.split(",").sort
For something a little different, let's not split at all.
people = gets.scan(/[^,]+/).map(&:strip).sort
This will avoid problems like multiple commas in a row yielding empty strings. Of course, you could also avoid that with:
people = gets.split(/\,+/).map(&:strip).sort

Get a value from an array of hashes in ruby

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]

Better way to loop through a set of hashes assigning array values in Ruby

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

Ruby: A neat way to find the number of non nil records from a Hashie::Mash

I'm using EJ Holme's rather excellent restforce gem to speak to my salesforce instance.
It's returning a hashie mash for a client record. I'd like to do a bit of built-in-method fu, but I'm getting stuck.
The hash returns around 550 array pairs of values. For instance Restforce_hash.last would return something like:
["field_title", "field_content">]
So far so great, I want to put a summary box at the top that displays a metric for how many fields are in use for the record.
If I call Restforce_hash.length I get the total number returned just fine.
However what I really want is the number of record pairs where the second item in the array (ie.. the "field_content" is not nil.
I was hoping there would be some great neat one-line ruby method for this like:
Restforce_hash.not_nil.length
But i'm not having just joy tracking something down... is there a way or do i have to iterate over the hash and count the number of != nil records?
Try this:
restforce_hash.count { |key, val| !val.nil? }
Restforce_hash.select{|key,value| value.present? }
will return all the elements after excluding all the NIL + blank elements.
if
Restforce_hash={:a=> "sss", :b=>"cvcxc",:c=>"",:f=>nil}
then
Restforce_hash.select{|key,value| value.present? }
will return
{:a=>"sss", :b=>"cvcxc"}
If you want to know how many nil values there are in a hash, just use:
hash = {a:1, b:nil, c:2}
hash.values.count{ |v| !v } # => 1

Return a single key from a Hash?

I would like to know how to return a specific key from a Hash?
Example:
moves = Hash["Kick", 100, "Punch", 50]
How would I return the first key "Kick" from this Hash?
NOTE: I'm aware that the following function will return all keys from the hash but I'm just interested in returning one key.
moves.keys #=> ["Kick", "Punch"]
You can use:
first_key, first_value = moves.first
Or equivalently:
first_key = moves.first.first
Quite nice too:
first_key = moves.each_key.first
The other possibility, moves.keys.first will build an intermediary array for all keys which could potentially be very big.
Note that Ruby 1.8 makes no guarantee on the order of a hash, so the key you will get not always be the same. In Ruby 1.9, you will always get the same key ("Kick" in your example).
moves.keys[0]
will give you the first key.
You can get all keys by changing the argument passed (0, 1,...etc)
moves.keys.first will accomplish that.

Resources