How to extract from an array of hash - ruby

people = [
{id: 101, first_name: 'John', last_name: 'Doe'},
{id: 102, first_name: 'Tom', last_name: 'Rogers'},
{id: 103, first_name: 'Bill', last_name: ''}
]
I want to put a list of name like this
"John Doe, Tom Rogers, Bill"
How can i achieve this is in ruby?

Input
people = [
{ id: 101, first_name: 'John', last_name: 'Doe' },
{ id: 102, first_name: 'Tom', last_name: 'Rogers' },
{ id: 103, first_name: 'Bill', last_name: '' }
]
Code
p people.map { |x| x[:first_name].to_s + ' ' + x[:last_name].to_s }
.map(&:strip)
.join(",")
Output
"John Doe,Tom Rogers,Bill"

The other answers are good, but I wanted to add a demonstration of string interpolation.
people
.map { |p| "#{p[:first_name]} #{p[:last_name]}" }
.join(", ")
#rajagopalan has a good idea in using strip to remove unwanted whitespace at the beginning and end of the first and last name combination, but it might be even better to run this on each component of the name.
people
.map { |p| "#{p[:first_name].strip} #{p[:last_name].strip}" }
.join(", ")

I would do
people
.map { |p| p.values_at(:first_name, :last_name).join(' ').strip }
.join(', ')
#=> "John Doe, Tom Rogers, Bill"
or
people
.map { |p| "#{p[:first_name]} #{p[:last_name]}".strip }
.join(', ')
#=> "John Doe, Tom Rogers, Bill"

Related

return data from an array based on filters

I have following array
person = [ {name: 'bob', weight: '160 lbs', hair: 'brown'},
{name: 'bob', weight: '160 lbs', hair: 'brown'},
{name: 'bob1', weight: '160 lbs', hair: 'brown'},
{name: 'bob1', weight: '160 lbs', hair: 'brown'},
{name: 'bob1', weight: '160 lbs', hair: 'brown'}
]
I am trying to get the data from array based on input params name and hair so they can be passed as single or in combination.
I tried following code and it works when name and hair are passed but if i just pass hair, it returns error undefined local variable or method name.
Here are the cases i am trying to achieve:
If name = bob and hair = brown passed it should return the first two hash having name: 'bob' and for bob1 last three hash having name: 'bob1' and If only weight or hair is passed it should return the entire array.
I believe i can write conditions based on parameters e.g if name && hair, if hair but then i'll have to repeat the code where i am selecting from array. So trying to figure out if it could be done with more cleaner way.
how can i update it so i could pass name, hair and also weight, one or in combination?
person.select { |hash| hash[:name] == name && hash[:hair] == hair }
The code I am executing is:
person = [ {name: 'bob', weight: '160 lbs', hair: 'brown'},
{name: 'bob', weight: '160 lbs', hair: 'brown'},
{name: 'bob1', weight: '160 lbs', hair: 'brown'},
{name: 'bob1', weight: '160 lbs', hair: 'brown'},
{name: 'bob1', weight: '160 lbs', hair: 'brown'}
]
# hair = 'brown'
# name = 'bob'
# person.select { |hash| hash[:name] == name &&
# hash[:hair] == hair }
# -->[{:name=>"bob", :weight=>"160 lbs", :hair=>"brown"}, {:name=>"bob", :weight=>"160 lbs", :hair=>"brown"}]
# hair = 'brown'
# name = 'bob1'
# person.select { |hash| hash[:name] == name &&
# hash[:hair] == hair }
# -->[{:name=>"bob1", :weight=>"160 lbs", :hair=>"brown"}, {:name=>"bob1", :weight=>"160 lbs", :hair=>"brown"}, {:name=>"bob1", :weight=>"160 lbs", :hair=>"brown"}]
hair = 'brown'
person.select { |hash| hash[:name] == name &&
hash[:hair] == hair }
# --> return entire person array
person = [
{ name: 'Bob', weight: '160 lbs', hair: 'brown' },
{ name: 'Bub', weight: '170 lbs', hair: 'none' },
{ name: 'Wilma', weight: '160 lbs', hair: 'brown' },
{ name: 'Gertrude', weight: '120 lbs', hair: 'blue' },
{ name: 'Bob', weight: '160 lbs', hair: 'brown' }
]
def select_matches(person, target)
keys = target.keys
person.select { |h| h.select { |k| keys.include?(k) } == target }
end
select_matches(person, name: 'Bob', weight: '160 lbs', hair: 'brown')
#=> [{:name=>"Bob", :weight=>"160 lbs", :hair=>"brown"},
# {:name=>"Bob", :weight=>"160 lbs", :hair=>"brown"}]
select_matches(person, weight: '160 lbs', hair: 'brown')
#=> [{:name=>"Bob", :weight=>"160 lbs", :hair=>"brown"},
# {:name=>"Wilma", :weight=>"160 lbs", :hair=>"brown"},
# {:name=>"Bob", :weight=>"160 lbs", :hair=>"brown"}]
select_matches(person, name: 'Gertrude')
#=> [{:name=>"Gertrude", :weight=>"120", :hair=>"blue"}]
Note that
select_matches(person, weight: '160 lbs', hair: 'brown')
is shorthand for
select_matches(person, { weight: '160 lbs', hair: 'brown' })
In Ruby 2.5 the penultimate line can be written
person.select { |h| h.slice(*keys) == target }
See Hash#slice. Slice is nice, eh?

How do I convert a Ruby hash so that all of its keys are strings

I have a ruby hash which looks like:
{ id: 123, name: "test" }
I would like to convert it to:
{ "id" => 123, "name" => "test" }
If you are using Rails or ActiveSupport:
hash = { id: 123, description: "desc" }
hash.stringify #=> { "id" => 123, "name" => "test" }
If you are not:
hash = { id: 123, name: "test" }
Hash[hash.map { |key, value| [key.to_s, value] }] #=> { "id" => 123, "name" => "test" }
I love each_with_object in this case :
hash = { id: 123, name: "test" }
hash.each_with_object({}) { |(key, value), h| h[key.to_s] = value }
#=> { "id" => 123, "name" => "test" }
In pure Ruby (without Rails), you can do this with a combination of Enumerable#map and Array#to_h:
hash = { id: 123, name: "test" }
hash.map{|key, v| [key.to_s, v] }.to_h
{ id: 123, name: "test" }.transform_keys(&:to_s)
#=> {"id"=>123, "name"=>"test"}
See Hash#transform_keys.

Ruby map specific hash keys to new one

I've got an array full of hashes of which I want to combine specific keys to a new one, e.g.
[{ firstname: 'john', lastname: 'doe', something: 'else', key: ... }, { firstname: 'Joe', lastname: 'something', something: 'bla', key:... }]
should become
[{ name: 'john doe' },{ name: 'Joe something' }]
Please note: there are more keys in the hash as first and lastname. Is there a common ruby method to do this? Thanks!
Just do as
array = [{ firstname: 'john', lastname: 'doe' }, { firstname: 'Joe', lastname: 'something' }]
array.map { |h| { :name => h.values_at(:firstname, :lastname) * " " } }
# => [{:name=>"john doe"}, {:name=>"Joe something"}]
Read this Hash#values_at and Array#* .
This is:
a = [{ firstname: 'john', lastname: 'doe' }, { firstname: 'Joe', lastname: 'something' }]
a.map { |n| { name: n.values.join(' ') } }
# => [{:name=>"john doe"}, {:name=>"Joe something"}]

Split array. Ruby

Could you help me please with some problem?
I have array from database like this
str = Hiring::Tag.all
Hiring::Tag Load (0.1ms) SELECT `hiring_tags`.* FROM `hiring_tags`
=> [#<Hiring::Tag id: 1, name: "tag1", created_at: "2013-12-10 11:44:39", updated_at: "2013-12-10 11:44:39">,
#<Hiring::Tag id: 2, name: "tag2", created_at: nil, updated_at: nil>,
#<Hiring::Tag id: 3, name: "tag3", created_at: nil, updated_at: nil>,
#<Hiring::Tag id: 4, name: "wtf", created_at: "2013-12-11 07:53:04", updated_at: "2013-12-11 07:53:04">,
#<Hiring::Tag id: 5, name: "new_tag", created_at: "2013-12-11 10:35:48", updated_at: "2013-12-11 10:35:48">]
And I need to split this array like this:
data:[{id:1,name:'tag1'},{id:2,name:'tag2'},
{id:3,name:'tag3'},{id:4,name:'wtf'},{id:5,name:'new_tag'}]
Help me please!
if you use ActiveRecord 4.0
Hiring::Tag.pluck(:id, :name).map{ |id, name| {id: id, name: name} }
One possible solution:
Hiring::Tag.all.map {|h| {id: h.id, name: h.name} }
See the documentation for map.
You can try below code.
Hiring::Tag.all.inject({}) { |h, f| h[f.name.to_sym] = f.value; h }
OR
Hiring::Tag.all.map { |f| [f.name.to_sym, f.value] }]

What is this format in ruby?

In a book they showed me this declaration:
friends = [ { first_name: "Emily", last_name: "Laskin" }, { first_name: "Nick", last_name: "Mauro" }, { first_name: "Mark", last_name: "Maxwell" } ]
This doesn't look like a hash. And when I enter it in IRB i get an error.
What is this format?
It's an array of hashes, written in the Ruby 1.9 hash syntax.
{ first_name: "Emily", last_name: "Laskin" }
is equivalent to:
{ :first_name => "Emily", :last_name => "Laskin" }
The {key: value} syntax is new in 1.9 and is equivalent to {:key => value}.
It is an array of hashes, only the hashes are 1.9 style hashes.

Resources