I would like to extract hash key values to an array when a condition is met. For example, with hash h I want to extract the keys where the values are "true":
h = { :a => true, :b => false, :c =>true }
I've come up with this:
h.map {|k,v| k if v==true} - [nil]
Any alternatives?
h.select { |_, v| v }.keys
Will do the same, but in more readable way.
You can also do
s = {}
h.each do |k,v|
s[k] = v if v==true
end
Related
I'm trying to find an elegant and compact way to convert hash keys into array that contains only those that have true as value
example = {"foo" => true, "bar" => false, "baz" => true}
become
example = ["foo", "baz"]
example = example.keys.select {|key| example[key].eql? true}
p example
output
["foo", "baz"]
The shortest would be example.select{|k, v| v}
to extract the keys simply add .keys
EDIT: if like Cary suggests there would be other than boolean values you would have to check for v == true or v.eql? true
My 2 cents:
example.collect{|k, v| k if v}.compact
output: ["foo", "baz"]
Which can work also picking false:
example.collect{|k, v| k if !v}.compact
output: ["bar"]
..or
There are a lot of different ways to do this. Here's another one:
example.reduce([]) { |memo, (k, v)| v ? memo << k : memo }
Or, similarly:
example.each_with_object([]) { |(k, v), memo| memo << k if v }
Or you can use my nutty piecewise gem:
example.piecewise { |yielder, (k, v)| yielder << k if v }
I have a hash that looks similar to:
hash = {key1: true, key2: false, key3: false, key4: true}
and I would like to iterate through the hash and print each key which has a true value. The result should look like:
key1
key4
How am I going to do that? I tried:
hash.each do |k,v|
puts k if true
end
While iterating is fine, the goal might be achieved in more rubyish manner:
hash.select { |_, v| v }.keys
or, if equality to true (as an opposite to being just truthy) is significant:
hash.select { |_, v| v == true }.keys
To print the result out:
puts hash.select { |_, v| v == true }.keys
Further information on how Hash#select works.
To print all the keys matched as “key1 and key4”:
puts hash.select { |_, v| v == true }.keys.join(' and ')
hash.each do |k, v|
puts k if v == true
end
You can use map and compact methods:
hash.map { |k, v| k if v }.compact
It is as simple as:
hash.each do |k,v|
puts k if v
end
Given a hash of key/value pairs, how can I turn that into an array of individual hashes for each key/value pair.
So for example, starting with:
{"hello"=>"bonjour", "goodbye"=>"au revoir"}
And turning that into:
[ {"hello" => "bonjour"}, {"goodbye" => "au revoir"} ]
I got that with the following but am wondering if there's an easier approach:
array = []
hash.each do |k,v|
h = Hash.new
h[k] = v
array << h
end
Do as below using Enumerable#map:
h = {"hello"=>"bonjour", "goodbye"=>"au revoir"}
h.map { |k,v| { k => v } }
# => [{"hello"=>"bonjour"}, {"goodbye"=>"au revoir"}]
I have a hash and I want to return the key(s) (or key/value pair(s)) of the max value(s) of the hash. So, if there is only one true max, it will return that one key; however, if there are multiple key/value pairs with the same value, it will return all of these keys. How can I accomplish this in Ruby?
my_hash.max_by {|k,v| v} #only returns one key/value pair
If you want all pairs, I would do something like
max = my_hash.values.max
Hash[my_hash.select { |k, v| v == max}]
A single liner:
my_hash.reduce({}){|h,(k,v)| (h[v] ||= []) << k;h}.max
irb
> z = {:tree => 3, :two => 2, 'three' => 3}
> z.reduce({}){|h,(k,v)| (h[v] ||= []) << k;h}.max
[3, [:tree, "three"]]
In some scenario of Ruby 1.8. If I have a hash
# k is name, v is order
foo = { "Jim" => 1, "bar" => 1, "joe" => 2}
sorted_by_values = foo.sort {|a, b| a[1] <==> b[1]}
#sorted_by_values is an array of array, it's no longer a hash!
sorted_by_values.keys.join ','
my workaround is to make method to_hash for Array class.
class Array
def to_hash(&block)
Hash[*self.collect { |k, v|
[k, v]
}.flatten]
end
end
I can then do the following:
sorted_by_values.to_hash.keys.join ','
Is there a better way to do this?
Hashes are unordered by definition. There can be no such thing as a sorted Hash. Your best bet is probably to extract the keys from the sorted array using collect and then do a join on the result
sortedByValues = foo.sort {|a, b| a[1] <==> b[1]}
sortedByValues.collect { |a| a[0] }.join ','