How to find a hash key containing a matching value
You could use Enumerable#select:
clients.select{|key, hash| hash["client_id"] == "2180" }
#=> [["orange", {"client_id"=>"2180"}]]
Note that the result will be an array of all the matching values, where each is an array of the key and value.
Find values in array of hashes to create new array of hashes
Pure ruby
array = [{:a=>'value1', :b=>'value2', :c=>'value3', :d=>'value4'}, {:a=>'value1', :b=>'value2', :c=>'value3', :d=>'value4'}]
b_and_c_array = array.map{|a| a.select{|k, _| [:b, :c].include?(k)} }
We take each hash using the map
method that will return a result array. For each hash, we select only [:b, :c]
keys. You can add more inside it.
Rails
If using Rails, let's use Hash#slice
, prettier :
b_and_c_array = array.map{|a| a.slice(:b, :c) }
Ruby how to find each value in hash greater than x?
You can use:
months.select { |_month, days| days > 30 }
This former gives you all results that fit the criteria (days > 30
).
Here are the docs:
select
Once you've got the values you need, you can then print them to the console (or output however you'd like), e.g.
long_months = months.select { |_month, days| days > 30 }
long_months.each { |month, days| puts "#{month} has #{days} days" }
All that being said, assigning to a value before printing the result means two loops, whereas this can be achieved in one using a simple each
:
months.each do |month, days|
puts("#{month} has #{days} days") if days > 30
end
That'll be more efficient as there's less churn involved :)
How do I search within an array of hashes by hash values in ruby?
You're looking for Enumerable#select (also called find_all
):
@fathers.select {|father| father["age"] > 35 }
# => [ { "age" => 40, "father" => "Bob" },
# { "age" => 50, "father" => "Batman" } ]
Per the documentation, it "returns an array containing all elements of [the enumerable, in this case @fathers
] for which block is not false."
How to find and return a hash value within an array of hashes, given multiple other values in the hash
You're on the right track!
results.find {|i| i["day"] == "2012-08-15" and i["name"] == "Bill"}["calls"]
# => "8"
Get hash values (from a number of hashes) in an array and sum them up
To sum the values of a hash:
{a:1,b:2}.values.sum
#=> 3
And to do that for your array of hashes:
total_order.flat_map(&:values).sum
#=> 15.0
Note that sum
is only available in Ruby 2.4.0 and later (and in Rails). In older versions you can use reduce(:+)
and inject(:+)
instead of sum
.
i want to make a group Hash by keys and add values
I'd use the each_with_object
method.(key, value)
here is a deconstruction of each key/value pair like 93=>1
, hash
is an intermediate object to store the result.
data.each_with_object({}) do |(key, value), hash|
result_key =
case key
when 10..19 then 1
when 20..29 then 2
when 90..99 then 9
end
next if result_key.nil?
hash[result_key] ||= 0
hash[result_key] += value
end
For the provided input I got {9=>2, 2=>7856, 1=>267}
UPD
A shorter solution suggested by Holger Just and Stefan in the comments below.
data.each_with_object(Hash.new(0)) do |(key, value), hash|
hash[key / 10] += value
end
With Hash.new(0)
the initial object will be a hash with the default value 0
> hash = Hash.new(0)
=> {}
> hash[1]
=> 0
Find key/value pairs deep inside a hash containing an arbitrary number of nested hashes and arrays
Here's a simple recursive solution:
def nested_hash_value(obj,key)
if obj.respond_to?(:key?) && obj.key?(key)
obj[key]
elsif obj.respond_to?(:each)
r = nil
obj.find{ |*a| r=nested_hash_value(a.last,key) }
r
end
end
h = { foo:[1,2,[3,4],{a:{bar:42}}] }
p nested_hash_value(h,:bar)
#=> 42
On Array of Hashes need to count values while creating other key pairs same time in ruby
You could use Enumerable#group_by.
aoh.group_by { |h| h[:interface] }
.map do |k,a|
n = a.count { |h| h[:status] == "online" }
{ interface: k, online_hosts: n, offline_hosts: a.size - n }
end
#=> [{:interface=>"1A", :online_hosts=>2, :offline_hosts=>1},
# {:interface=>"2A", :online_hosts=>1, :offline_hosts=>2}]
Note:
aoh.group_by { |h| h[:interface] }
#=> {"1A"=>[{:interface=>"1A", :host=>"host_1", :status=>"online"},
# {:interface=>"1A", :host=>"host_2", :status=>"online"},
# {:interface=>"1A", :host=>"host_3", :status=>"offline"}],
# "2A"=>[{:interface=>"2A", :host=>"host_4", :status=>"offline"},
# {:interface=>"2A", :host=>"host_5", :status=>"offline"},
# {:interface=>"2A", :host=>"host_6", :status=>"online"}]}
Another way is to use the form of Hash#update (a.k.a. merge!
) that employs a block to determine the value of keys that are present in both hashes being merged. Here that block is do |_,o,n| ... end
. See the doc for the definitions of the three block variables, _
, o
and n
. (_
holds the common key. I've used an underscore to represent that variable to signal to the reader that it is not used in the block calculation, a common convention.)
aoh.each_with_object({}) do |g,h|
h.update(
g[:interface]=>
{ interface: g[:interface],
online_hosts: g[:status] == "online" ? 1 : 0,
offline_hosts: g[:status] == "online" ? 0 : 1
}
) do |_,o,n|
{ interface: o[:interface],
online_hosts: o[:online_hosts]+n[:online_hosts],
offline_hosts: o[:offline_hosts]+n[:offline_hosts]
}
end
end.values
#=> [{:interface=>"1A", :online_hosts=>2, :offline_hosts=>1},
# {:interface=>"2A", :online_hosts=>1, :offline_hosts=>2}]
Note that the receiver of Hash#values is:
{"1A"=>{:interface=>"1A", :online_hosts=>2, :offline_hosts=>1},
"2A"=>{:interface=>"2A", :online_hosts=>1, :offline_hosts=>2}}
Related Topics
Convert This Xml Request to a Proper Savon Request
Instantiate Capybara Browser and Set a Proxy
How to Convert a Large Gem to Standalone Rails App
How to Set Up These Crud Controller Actions for Has_Many_Polymorphs and an Error
Invalid Route Name, Already in Use: 'Admin_Root' (Argumenterror) - Failed Activeadmin Install
Multiple Limit Condition in Mongodb
How to Properly Install Bootsnap on Windows
Ruby on Rails Group_By (How to Group Events by Month)
Consolidating Duplicate Array Items
Rails Strong Params - Using Fields from Has_Many Object
Ruby Stack Failed to Deploy on Google Developers Console
Setting a Text Field That Has a Jquery Mask on It
Why Rails Instance Method Can Be Used as Class Method in Rspec