[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Updating all values in a Hash

Paul Dugdale

5/13/2008 2:20:00 PM

Does anyone know a good way to update all values in a hash.

E.g. If I have a big hash with each element containing a string as a
value, how can I make each string lower-case?
--
Posted via http://www.ruby-....

9 Answers

Sebastian Hungerecker

5/13/2008 2:52:00 PM

0

Paul Dugdale wrote:
> If I have a big hash with each element containing a string as a
> value, how can I make each string lower-case?

hash.each {|k,v| v.downcase!}
Or if you can't use destructive methods:
hash.each {|k,v| hash[k] = v.downcase}

HTH,
Sebastian
--
NP: Depeche Mode - Strangelove
Jabber: sepp2k@jabber.org
ICQ: 205544826

Tim Pease

5/13/2008 2:57:00 PM

0

On May 13, 2008, at 8:20 AM, Paul Dugdale wrote:

> Does anyone know a good way to update all values in a hash.
>
> E.g. If I have a big hash with each element containing a string as a
> value, how can I make each string lower-case?


h = {1 => 'ONE', 2 => 'TWO'}
h.each {|k,v| v.downcase!}

This assumes that all your values really are strings. You'll get some
errors if any of the values do not have a downcase! methd.

Blessings,
TwP


Sandro Paganotti

5/13/2008 2:58:00 PM

0

I found this way

h = Hash.new

def h.[](val)
super.downcase
end

h["ciao"] = "CIOOOO"

puts h["ciao"]
# cioooo

On Tue, May 13, 2008 at 2:20 PM, Paul Dugdale <p.dugdale@gmail.com> wrote:
> Does anyone know a good way to update all values in a hash.
>
> E.g. If I have a big hash with each element containing a string as a
> value, how can I make each string lower-case?
> --
> Posted via http://www.ruby-....
>
>



--
Go outside! The graphics are amazing!

David A. Black

5/13/2008 3:17:00 PM

0

Hi --

On Tue, 13 May 2008, Sandro Paganotti wrote:

> On Tue, May 13, 2008 at 2:20 PM, Paul Dugdale <p.dugdale@gmail.com> wrote:
>> Does anyone know a good way to update all values in a hash.
>>
>> E.g. If I have a big hash with each element containing a string as a
>> value, how can I make each string lower-case?
>> --
>> Posted via http://www.ruby-....
>>
>>
>
> I found this way
>
> h = Hash.new
>
> def h.[](val)
> super.downcase
> end
>
> h["ciao"] = "CIOOOO"
>
> puts h["ciao"]
> # cioooo

That's very resourceful (I'm fully in favor of extending individual
objects), but I'm afraid it doesn't really do what Paul wants. All it
does is downcase what you see when you do h[val]. But the actual value
doesn't change:

>> h = {}
=> {}
>> def h.[](val); super.downcase; end
=> nil
>> h["a"] = "ABC"
=> "ABC"
>> h["a"] # This gives you downcased string.
=> "abc"
>> h.fetch("a") # But this doesn't.
=> "ABC"
>> h.values # Neither does this.
=> ["ABC"]


I think also that Paul is dealing with a hash that already has some
values, so the iterative solutions might be better.


David

--
Rails training from David A. Black and Ruby Power and Light:
INTRO TO RAILS June 9-12 Berlin
ADVANCING WITH RAILS June 16-19 Berlin
INTRO TO RAILS June 24-27 London (Skills Matter)
See http://www.r... for details and updates!

Paul Dugdale

5/13/2008 3:46:00 PM

0

Sorry! I was trying to keep my post simple, but ended up doing a really
bad job of explaining what I was trying to achieve...

I come from a C programming background, so I'm always thinking in terms
of pass-by-value and pass-by-reference.

What I was trying to find out is - is there any way of passing a
reference to the value to the 'each' block, rather than a copy of the
value.

I.e. some easy way of doing this:
hash.each { |k,v| v = my_value }

Without having to refer to the hash again in the block like this:
hash.each { |k,v| hash[k] = my_value }
--
Posted via http://www.ruby-....

Sebastian Hungerecker

5/13/2008 4:04:00 PM

0

Paul Dugdale wrote:
> What I was trying to find out is - is there any way of passing a
> reference to the value to the 'each' block, rather than a copy of the
> value.

You always pass by reference, but you pass a reference to the object (a
pointer if you will) not a reference to the variable. You can't have variable
references in ruby.


> I.e. some easy way of doing this:
> hash.each { |k,v| v = my_value }

v.replace my_value
If v has a replace method


> Without having to refer to the hash again in the block like this:
> hash.each { |k,v| hash[k] = my_value }

If your v object is immutable, you'll have to do the above, I'm afraid.


HTH,
Sebastian
--
NP: Depeche Mode - Useless
Jabber: sepp2k@jabber.org
ICQ: 205544826

Robert Klemme

5/13/2008 4:12:00 PM

0

On 13.05.2008 17:46, Paul Dugdale wrote:
> Sorry! I was trying to keep my post simple, but ended up doing a really
> bad job of explaining what I was trying to achieve...
>
> I come from a C programming background, so I'm always thinking in terms
> of pass-by-value and pass-by-reference.
>
> What I was trying to find out is - is there any way of passing a
> reference to the value to the 'each' block, rather than a copy of the
> value.

A reference is indeed passed to the block. There is no copying of
values going on. You can see it because v.downcase! works; this does
change the object referenced by the Hash.

> I.e. some easy way of doing this:
> hash.each { |k,v| v = my_value }
>
> Without having to refer to the hash again in the block like this:
> hash.each { |k,v| hash[k] = my_value }

I'm afraid, you'll have to use that idiom. The only alternative is to
change your scenario so that it will modify an object, e.g. create an
intermediary:

irb(main):001:0> Holder = Struct.new :val
=> Holder
irb(main):002:0> h={1=>Holder.new(123)}
=> {1=>#<struct Holder val=123>}
irb(main):003:0> h.each {|k,v| v.val += 10}
=> {1=>#<struct Holder val=133>}
irb(main):004:0>

I doubt though that this is more efficient that using any of

h.keys.each {|k| h[k] += 10}
h.each {|k,v| h[k] = v + 10}

What is the greater context of your issue, i.e. what are you trying to
achieve?

Kind regards

robert

Rick DeNatale

5/13/2008 9:53:00 PM

0

On Tue, May 13, 2008 at 12:04 PM, Sebastian Hungerecker
<sepp2k@googlemail.com> wrote:
> Paul Dugdale wrote:
> > What I was trying to find out is - is there any way of passing a
> > reference to the value to the 'each' block, rather than a copy of the
> > value.

> > Without having to refer to the hash again in the block like this:
> > hash.each { |k,v| hash[k] = my_value }
>
> If your v object is immutable, you'll have to do the above, I'm afraid.

Even if it isn't not doing so can be problematic:

a = "Fred"
h = {:flintstone => a}
a # => "Fred"
h # => {:flintstone=>"Fred"}
h.each {|k,v| v.downcase!}
h # => {:flintstone=>"fred"}
# Expected, but...

a # => "fred"
# Expected????!!!!

Understanding how object reference differs from pointer reference and
value semantics is crucial to starting to understand a pure object
language like Ruby.

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denh...

David A. Black

5/14/2008 1:18:00 AM

0

Hi --

On Wed, 14 May 2008, Sebastian Hungerecker wrote:

> Paul Dugdale wrote:
>> What I was trying to find out is - is there any way of passing a
>> reference to the value to the 'each' block, rather than a copy of the
>> value.
>
> You always pass by reference, but you pass a reference to the object (a
> pointer if you will) not a reference to the variable. You can't have variable
> references in ruby.

I'd put it differently, and I know this sounds convoluted but I think
in the end it turns out to be more apt: You're passing by value, but
the value you're passing is a reference to an object.

"Passing by reference" makes it sound (to me) like when you do this:

s = "hi"
my_method(s)

s somehow gets wrapped in a reference on its way to my_method, whereas
it's actually really just being handed off. The value assigned to the
corresponding parameter in my_method is the same as the value of s:
namely, a reference to that string.

There's probably some aspect of using literal constructors as method
arguments that needs to be factored in there somewhere....


David

--
Rails training from David A. Black and Ruby Power and Light:
INTRO TO RAILS June 9-12 Berlin
ADVANCING WITH RAILS June 16-19 Berlin
INTRO TO RAILS June 24-27 London (Skills Matter)
See http://www.r... for details and updates!