I have an array of hashes - @profiles which has data as:
[{:user_id=>5, :full_name=>"Emily Spot"},{:user_id=>7, :full_name=>"Kevin Walls"}]
I want to get full_name of say user_id = 7? I'm doing the following: but it's throwing an error that expression @profiles.find{|h| h[':user_id'] == current_user.id}
is nil.
name = @profiles.find{ |h| h[':user_id'] == current_user.id }[':full_name']
if I use select
instead of find
then error is - no implicit conversion of String into Integer.
How do I search through the array of hashes?
UPDATE:
After @Eric's answer, I restructured my job model & view actions:
def full_names
profile_arr||= []
profile_arr = self.applications.pluck(:user_id)
@profiles = Profile.where(:user_id => profile_arr).select([:user_id, :first_name, :last_name]).map {|e| {user_id: e.user_id, full_name: e.full_name} }
@full_names = @profiles.each_with_object({}) do |profile, names|
names[profile[:user_id]] = profile[:full_name]
end
end
In the view....,
p @current_job.full_names[current_user.id]
@profiles
is an array of hashes, with symbols as keys, whereas what you use is String
objects.
So ':user_id'
is a string, and you want symbol: :user_id
:
@profiles.find{ |h| h[:user_id] == current_user.id }
I want to get
full_name
of sayuser_id == 7
@profiles.find { |hash| hash[:user_id] == 7 }.fetch(:full_name, nil)
Note, I used Hash#fetch
for case, when there is no hash with value 7
at key :user_id
.
As you've noticed, it's not very convenient to extract the name of user_id
7. You could modify your data structure a bit :
@profiles = [{:user_id=>5, :full_name=>"Emily Spot"},
{:user_id=>7, :full_name=>"Kevin Walls"}]
@full_names = @profiles.each_with_object({}) do |profile, names|
names[profile[:user_id]] = profile[:full_name]
end
p @full_names
# {5=>"Emily Spot", 7=>"Kevin Walls"}
p @full_names[7]
# "Kevin Walls"
p @full_names[6]
# nil
You didn't lose any information but name look-up is now much faster, easier and more robust.
Suggesting, to create a new hash that can make things simpler
Eg:
results = {}
profiles = [
{user_id: 5, full_name: "Emily Spot"},
{user_id: 7, full_name: "Kevin Walls"}
]
profiles.each do |details|
results[details[:user_id]] = details[:full_name]
end
Now, results will have:
{5: "Emily Spot", 7: "Kevin Walls"}
So, if you need to get full_name of say user_id = 7, simply do:
results[7] # will give "Kevin Walls"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With