Subselecting hash back into hash (oneliner?)


#1

Going through pick-axe and was just wondering if there was a one
liner for something such as this that I may have missed:

h2 = Hash.new
h1 = {“foo1”=>“bar1”, “foo2”=>“bar2”}
query = h1.select { |k,v| v == “bar2” }
query.each do |result|
h2[result[0]] = result[1]
end
p h2

Thanks.

  • Jon

#2

On Jan 26, 2006, at 1:59 PM, Jon B. wrote:

Going through pick-axe and was just wondering if there was a one
liner for something such as this that I may have missed:

h2 = Hash.new
h1 = {“foo1”=>“bar1”, “foo2”=>“bar2”}
query = h1.select { |k,v| v == “bar2” }
query.each do |result|
h2[result[0]] = result[1]
end
p h2

Like this?

h1 = {“foo1”=>“bar1”, “foo2”=>“bar2”}
=> {“foo1”=>“bar1”, “foo2”=>“bar2”}

h2 = Hash[*h1.select { |k, v| v == “bar2” }.flatten]
=> {“foo2”=>“bar2”}

Hope that helps.

James Edward G. II


#3

Jon B. wrote:

Thanks.

  • Jon

Perhaps:

h2 = Hash.new
h1 = {“foo1”=>“bar1”, “foo2”=>“bar2”}
h2 = h1.delete_if{|k,v| v != “bar2”}
p h2


#4

Nice … well that works :slight_smile: but in the constructor can you tell me
what “*” would literally “mean”?

Does this just take only an Array obj or could you place any object
in there w/ public attributes/methods?

(Was this covered in pick-axe somewhere I missed?)

Thank you, much appreciated …

  • Jon

#5

On Jan 26, 2006, at 4:55 PM, Jon B. wrote:

Nice … well that works :slight_smile: but in the constructor can you tell me
what “*” would literally “mean”?

I see you’ve already got this answer.

Does this just take only an Array obj or could you place any object
in there w/ public attributes/methods?

I’m not sure what “this” refers to in the above sentence. Try asking
your question again, please.

(Was this covered in pick-axe somewhere I missed?)

I just looked an can’t seem to find it. It’s the opposite of the *
operator described on page 347 (explodes an Array out, instead of
collecting it in).

James Edward G. II


#6

On Jan 26, 2006, at 2:55 PM, Jon B. wrote:

  • Jon

On Jan 26, 2006, at 3:06 PM, James Edward G. II wrote:

h1 = {“foo1”=>“bar1”, “foo2”=>“bar2”}
=> {“foo1”=>“bar1”, “foo2”=>“bar2”}

h2 = Hash[*h1.select { |k, v| v == “bar2” }.flatten]

The “*” is sometimes called the “splat” operator. If you use the Hash
[] constructor and pass in an array with the * before it it will turn
the array into a hash using pairs of the array members to create the
key => values of the hash. Maybe a littel more code tells it best:

ezra:~/up root# irb
irb(main):001:0> a = [1,2,3,4,5,6,7,8]
=> [1, 2, 3, 4, 5, 6, 7, 8]
irb(main):002:0> b = Hash[*a]
=> {5=>6, 1=>2, 7=>8, 3=>4}
irb(main):003:0> h1 = {“foo1”=>“bar1”, “foo2”=>“bar2”}
=> {“foo1”=>“bar1”, “foo2”=>“bar2”}
irb(main):004:0> h1.select { |k, v| v == “bar2” }.flatten
=> [“foo2”, “bar2”]
irb(main):005:0> h2 = Hash[*h1.select { |k, v| v == “bar2” }.flatten]
=> {“foo2”=>“bar2”}
irb(main):006:0>

Cheers-
-Ezra


#7

James Edward G. II schrieb:

(Was this covered in pick-axe somewhere I missed?)

I just looked an can’t seem to find it. It’s the opposite of the *
operator described on page 347 (explodes an Array out, instead of
collecting it in).

Pickaxe 1, page 229, “Invoking a Method”. Online here:

http://phrogz.net/ProgrammingRuby/language.html#invokingamethod

Regards,
Pit