Question on iterating a hash


#1

I have a hash that looks like this : {“1”=>"0, “3”=“1”, “45”=>“1”,
“101”=>“0”}

What I want is an array of all the keys that have hash values equal to
“1” [“3”,“45”] in this case.

Yeah, i can just iterate the keys… but it seems like there is a “ruby”
way to do this. Any thoughts?

thx
phil


#2

On Jan 4, 2006, at 12:46 PM, phil swenson wrote:

I have a hash that looks like this : {“1”=>"0, “3”=“1”, “45”=>“1”,
“101”=>“0”}

What I want is an array of all the keys that have hash values equal to
“1” [“3”,“45”] in this case.

Yeah, i can just iterate the keys… but it seems like there is a
“ruby”
way to do this. Any thoughts?

h = Hash[*%w{1 0 3 1 45 1 101 0}]
=> {“45”=>“1”, “1”=>“0”, “101”=>“0”, “3”=>“1”}

h.select { |key, value| value == “1” }.map { |key, value| key }
=> [“45”, “3”]

Hope that helps.

James Edward G. II


#3

phil swenson wrote:

phil

{“1”=>“0”, “3”=>“1”, “45”=>“1”,“101”=>“0”}.select{|k,v|
v==“1”}.map{|e|e.first}

lopex


#4

Hi –

On Thu, 5 Jan 2006, James Edward G. II wrote:

h = Hash[*%w{1 0 3 1 45 1 101 0}]
=> {“45”=>“1”, “1”=>“0”, “101”=>“0”, “3”=>“1”}

h.select { |key, value| value == “1” }.map { |key, value| key }
=> [“45”, “3”]

Wouldn’t it be easier to iterate through the keys? I’m not sure why
Phil didn’t want to. (Phil?)

h.keys.select {|k| h[k] == 1}

David


David A. Black
removed_email_address@domain.invalid

“Ruby for Rails”, from Manning Publications, coming April 2006!


#5

On Thu, 5 Jan 2006, removed_email_address@domain.invalid wrote:

h.keys.select {|k| h[k] == 1}

s/1/“1”/ :slight_smile:


David A. Black
removed_email_address@domain.invalid

“Ruby for Rails”, from Manning Publications, coming April 2006!


#6

removed_email_address@domain.invalid wrote:

“1” [“3”,“45”] in this case.

=> [“45”, “3”]

Wouldn’t it be easier to iterate through the keys? I’m not sure why
Phil didn’t want to. (Phil?)

h.keys.select {|k| h[k] == 1}

David

Don’t know, but here is another one:

h.select{|k, v| v == “1” }.transpose.first

cheers

Simon


#7

Wouldn’t it be easier to iterate through the keys? I’m not sure why
Phil didn’t want to. (Phil?)

h.keys.select {|k| h[k] == 1}

Since he wants the keys of the hash in an array, wouldn’t you need to do
this…

result = h.keys.select {|k| h[k] == 1}
result = result.keys

I’m sure there’s a one-liner for this somewhere, but I need more coffee.


#8

On Thu, 5 Jan 2006, Kevin O. wrote:

result = result.keys
No. h.keys is an array, and select returns an array.

David


David A. Black
removed_email_address@domain.invalid

“Ruby for Rails”, from Manning Publications, coming April 2006!


#9

unknown wrote:

On Thu, 5 Jan 2006, Kevin O. wrote:

result = result.keys
No. h.keys is an array, and select returns an array.

See, I told you I needed more coffee.


#10

Hi –

On Thu, 5 Jan 2006, Kevin O. wrote:

unknown wrote:

On Thu, 5 Jan 2006, Kevin O. wrote:

result = result.keys
No. h.keys is an array, and select returns an array.

See, I told you I needed more coffee.

I know the feeling well. That’s why we have multiple people on the
list – to take up the caffeine slack for each other :slight_smile:

David


David A. Black
removed_email_address@domain.invalid

“Ruby for Rails”, from Manning Publications, coming April 2006!


#11

On 1/4/06, phil swenson removed_email_address@domain.invalid wrote:

Yeah, i can just iterate the keys… but it seems like there is a “ruby”
way to do this. Any thoughts?

Another option:

h.map{|k,v| k if v==‘1’}.compact

And of course an inject version:
h.inject([]){|a,b| a<<b[0] if b[1]==‘1’;a}

Ryan


#12

On 1/4/06, removed_email_address@domain.invalid removed_email_address@domain.invalid wrote:

If you’re sure nil isn’t a key :slight_smile:

True. But I’d love to see a real-world example of someone doing that.
Sounds like code-smell to me.

Ryan


#13

Hi –

On Thu, 5 Jan 2006, Ryan L. wrote:

On 1/4/06, phil swenson removed_email_address@domain.invalid wrote:

Yeah, i can just iterate the keys… but it seems like there is a “ruby”
way to do this. Any thoughts?

Another option:

h.map{|k,v| k if v==‘1’}.compact

If you’re sure nil isn’t a key :slight_smile:

David


David A. Black
removed_email_address@domain.invalid

“Ruby for Rails”, from Manning Publications, coming April 2006!


#14

On Thu, 5 Jan 2006, Ryan L. wrote:

On 1/4/06, removed_email_address@domain.invalid removed_email_address@domain.invalid wrote:

If you’re sure nil isn’t a key :slight_smile:

True. But I’d love to see a real-world example of someone doing that.
Sounds like code-smell to me.

I’d be very suprised if it ever happened. But I still like the simple
select version best :slight_smile:

David


David A. Black
removed_email_address@domain.invalid

“Ruby for Rails”, from Manning Publications, coming April 2006!


#15

Ryan L. wrote:

h.inject([]){|a,b| a<<b[0] if b[1]==‘1’;a}
You can even access key and value separately:

h.inject([]) {|a,(k,v)| a << k if v == ‘1’; a}

:slight_smile:

robert

#16

Hi –

On Thu, 5 Jan 2006, Simon Kröger wrote:

David

Don’t know, but here is another one:

h.select{|k, v| v == “1” }.transpose.first

OK… but I’m still not getting why just "select"ing the ones you want
isn’t the best way.

David


David A. Black
removed_email_address@domain.invalid

“Ruby for Rails”, from Manning Publications, coming April 2006!


#17

Kevin O. removed_email_address@domain.invalid wrote:

result = h.keys.select {|k| h[k] == 1}

i think it’s more :
h.keys.select {|k| h[k] == “1”}

if h is really :
h = Hash[*%w{1 0 3 1 45 1 101 0}]

that’s to say String not Fixnum ))