Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby: Easiest Way to Filter Hash Keys?

Tags:

ruby

I have a hash that looks something like this:

params = { :irrelevant => "A String",            :choice1 => "Oh look, another one",            :choice2 => "Even more strings",            :choice3 => "But wait",            :irrelevant2 => "The last string" } 

And I want a simple way to reject all the keys that aren't choice+int. It could be choice1, or choice1 through choice10. It varies.

How do I single out the keys with just the word choice and a digit or digits after them?

Bonus:

Turn the hash into a string with tab (\t) as a delimiter. I did this, but it took several lines of code. Usually master Rubicians can do it in one or so lines.

like image 790
Derek Avatar asked Sep 15 '11 11:09

Derek


People also ask

Can you sort a hash in Ruby?

Sorting Hashes in RubyTo sort a hash in Ruby without using custom algorithms, we will use two sorting methods: the sort and sort_by. Using the built-in methods, we can sort the values in a hash by various parameters.

How do you check if a hash has a key Ruby?

Overview. We can check if a particular hash contains a particular key by using the method has_key?(key) . It returns true or false depending on whether the key exists in the hash or not.


2 Answers

Edit to original answer: Even though this is answer (as of the time of this comment) is the selected answer, the original version of this answer is outdated.

I'm adding an update here to help others avoid getting sidetracked by this answer like I did.

As the other answer mentions, Ruby >= 2.5 added the Hash#slice method which was previously only available in Rails.

Example:

> { one: 1, two: 2, three: 3 }.slice(:one, :two) => {:one=>1, :two=>2} 

End of edit. What follows is the original answer which I guess will be useful if you're on Ruby < 2.5 without Rails, although I imagine that case is pretty uncommon at this point.


If you're using Ruby, you can use the select method. You'll need to convert the key from a Symbol to a String to do the regexp match. This will give you a new Hash with just the choices in it.

choices = params.select { |key, value| key.to_s.match(/^choice\d+/) } 

or you can use delete_if and modify the existing Hash e.g.

params.delete_if { |key, value| !key.to_s.match(/choice\d+/) } 

or if it is just the keys and not the values you want then you can do:

params.keys.select { |key| key.to_s.match(/^choice\d+/) } 

and this will give the just an Array of the keys e.g. [:choice1, :choice2, :choice3]

like image 82
mikej Avatar answered Sep 23 '22 15:09

mikej


In Ruby, the Hash#select is a right option. If you work with Rails, you can use Hash#slice and Hash#slice!. e.g. (rails 3.2.13)

h1 = {:a => 1, :b => 2, :c => 3, :d => 4}  h1.slice(:a, :b)         # return {:a=>1, :b=>2}, but h1 is not changed  h2 = h1.slice!(:a, :b)   # h1 = {:a=>1, :b=>2}, h2 = {:c => 3, :d => 4} 
like image 29
lfx_cool Avatar answered Sep 23 '22 15:09

lfx_cool