Ok - in 'awk' you can do this: (Where 'array' is empty initially)
array[<string>]++
For instance:
array["abc"]++; => a["abc"]=1
array["abc"]++; => a["abc']=2
...
Which is really useful for tallying up a complete column of varying
values from a text file where you don't know in advance the what may
appear in a column etc...
In Ruby, I have worked out a similar the equivalent to be: (with a Hash
now...)
a={};
a["abc"]=a["abc"].to_i+1;
But I"m sure there is a shorter way ? Better trick available here?
As an aside to 'to_i' is to turn the 'nil' into zero: is this safe to
assume this?
Thanks - sorry if this is stupid question....
John
···
--
Posted via http://www.ruby-forum.com/.
No stupid questions; they're all good.
Here's a minor reworking of what you did to eliminate the #to_i.
a = Hash.new { |h,k| h[k] = 0 }
a["abc"] += 1
The special form of Hash.new that I used above will automatically initialize the bucket to 0 for any new key it receives, so you avoid the problem with nil and #to_i.
cr
···
On Aug 7, 2008, at 4:59 PM, John Pritchard-williams wrote:
Ok - in 'awk' you can do this: (Where 'array' is empty initially)
array[<string>]++
For instance:
array["abc"]++; => a["abc"]=1
array["abc"]++; => a["abc']=2
...
Which is really useful for tallying up a complete column of varying
values from a text file where you don't know in advance the what may
appear in a column etc...
In Ruby, I have worked out a similar the equivalent to be: (with a Hash
now...)
a={};
a["abc"]=a["abc"].to_i+1;
But I"m sure there is a shorter way ? Better trick available here?
As an aside to 'to_i' is to turn the 'nil' into zero: is this safe to
assume this?
Thanks - sorry if this is stupid question....
Quite true, but I find the block form to be a better "general case" form to know since it is so much more flexible. But that's just my preference.
cr
···
On Aug 7, 2008, at 5:27 PM, Siep Korteling wrote:
Chuck Remes wrote:
On Aug 7, 2008, at 4:59 PM, John Pritchard-williams wrote:
a["abc"]=a["abc"].to_i+1;
But I"m sure there is a shorter way ? Better trick available here?
As an aside to 'to_i' is to turn the 'nil' into zero: is this safe to
assume this?
Thanks - sorry if this is stupid question....
No stupid questions; they're all good.
Here's a minor reworking of what you did to eliminate the #to_i.
a = Hash.new { |h,k| h[k] = 0 }
a["abc"] += 1
The special form of Hash.new that I used above will automatically
initialize the bucket to 0 for any new key it receives, so you avoid
the problem with nil and #to_i.
cr
a = Hash.new(0)
a["abc"] += 1
Has the same effect.
That's true in a way - although for this particular case I'd prefer
the solution with the default parameter. This can be slightly more
efficient at times because it does not insert a value on each query to
the Hash.
For other frequent cases, I use the block form. This is a typical
(for me) application:
items = Hash.new {|h,k| h[k] = }
...
items[item.category] << item
Kind regards
robert
···
2008/8/8 Chuck Remes <cremes.devlist@mac.com>:
On Aug 7, 2008, at 5:27 PM, Siep Korteling wrote:
Chuck Remes wrote:
On Aug 7, 2008, at 4:59 PM, John Pritchard-williams wrote:
a = Hash.new { |h,k| h[k] = 0 }
a["abc"] += 1
a = Hash.new(0)
a["abc"] += 1
Has the same effect.
Quite true, but I find the block form to be a better "general case" form to
know since it is so much more flexible. But that's just my preference.
--
use.inject do |as, often| as.you_can - without end
Quite true, but I find the block form to be a better "general case"
form to know since it is so much more flexible.
I guess you have a point here, but visually I find the shorter solution
a = Hash.new(0)
a['abc'] += 1
more appealing.
···
--
Posted via http://www.ruby-forum.com/\.
# I guess you have a point here, but visually I find the
# shorter solution
# a = Hash.new(0)
# a['abc'] += 1
# more appealing.
careful, it's more than a face; the previous block example creates/assigns objects when called.
compare this,
irb(main):001:0> h=Hash.new 0
=> {}
irb(main):002:0> h[1]
=> 0
irb(main):003:0> h[2]
=> 0
irb(main):004:0> h
=> {}
w this,
irb(main):005:0> h=Hash.new{|h,k| h[k]=0}
=> {}
irb(main):006:0> h[1]
=> 0
irb(main):007:0> h[2]
=> 0
irb(main):008:0> h
=> {1=>0, 2=>0}
and this,
irb(main):011:0* h=Hash.new{|h,k| 0}
=> {}
irb(main):012:0> h[1]
=> 0
irb(main):013:0> h[2]
=> 0
irb(main):014:0> h
=> {}
(note that Hash.new{|h,k| 0} may evolve to Hash.new{0} or Hash.new(0); ie all of them do not assign/create to the hash)
the common denominator of the above is that they all do the ff (w same result)
irb(main):021:0> h[1] += 1
=> 1
irb(main):022:0> h
=> {1=>1}
So if you ask me, i find the hash block form very generic.
kind regards -botp (just another block fan
···
From: Marc Heiler [mailto:shevegen@linuxmail.org]
Thanks for the replies: in fact I also prefer this one:
//
a = Hash.new(0)
a['abc'] += 1
//
As it matches exactly the behaviour of the 'awk' program and its also
kinda neat looking.
On the other hand this solution is also really intriguing: ( and I note
the difference in behaviour as explained earlier in this post):
//
h=Hash.new{|h,k| h[k]=0}
//
So can somebody explain in English what is going on here ? This is very
very Ruby to me I'm guessing that we are hanging that block of the
'store' method of 'h' from now on ? I mean: so when somebody then calls
something like:
h.store(mykey,myvalue) it will invoke the block which will result in:
h[mykey]=myvalue - but only if 'myvalue' is nil ?
Is this a very specific mechanism to hashes or something really generic?
Thanks again !
John
···
--
Posted via http://www.ruby-forum.com/.
# So can somebody explain in English what is going on here ?
# This is very very Ruby to me I'm guessing that we are
# hanging that block of the 'store' method of 'h' from now on ?
# I mean: so when somebody then calls something like:
···
From: John Pritchard-williams [mailto:monojohnny@googlemail.com]
#
# h.store(mykey,myvalue) it will invoke the block which will result in:
# h[mykey]=myvalue - but only if 'myvalue' is nil ?
no. nil is a value and could be value for a hash key.
try
h[mykey] = nil
the block form will invoke the block if the hash key does not exist
try
h.has_key? mykey
# Is this a very specific mechanism to hashes or something
# really generic?
imho, if you work on hashes, you should know block form of Hash.new. See ruby-doc for examples.
kind regards -botp
# Is this a very specific mechanism to hashes or something
# really generic?
imho, if you work on hashes, you should know block form of Hash.new. See
ruby-doc for examples.
Thanks ! Will check it out
Cheers
John
···
--
Posted via http://www.ruby-forum.com/\.