>
> seen_ary = Array.new
>
> File.open("nums","r").each do |elem|
> print elem if seen_ary.include?(elem)
> seen_ary.push(elem)
> end
>
> (there are probably still better ways of doing this though)
I'll go with:
seen = {}
ARGF.each do |elem|
print elem if seen.include? elem
seen[elem] = true
end
And yes, this way is much better (I knew it would be but, it's nice to
see just how much better):
require 'benchmark'
n = 100
# build a big array with lots of duplication @nums = (1..1_000).to_a
(1..1_000).step(17) {|num| @nums.push(num) }
# set up two versions of our rubylike version
# the original perl-like version and the
# final version
def as_ary
seen_ary = Array.new
@nums.each do |elem|
$stderr.print elem if seen_ary.include?(elem)
seen_ary.push(elem)
end
end
def as_hash
seen = Hash.new
@nums.each do |elem|
$stderr.print elem if seen.include?(elem)
seen[elem] = true
end
end
# then benchmark them to see how they perform
Benchmark.bm(10) do |x|
x.report("as Array") {for i in 1..n; as_ary; end }
x.report("as Hash") {for i in 1..n; as_hash; end }
end
# and the results are:
# ./print_dups.rb 2> /dev/null
# user system total real #as Array 12.690000 0.030000 12.720000 ( 13.940651) #as Hash 0.230000 0.000000 0.230000 ( 0.613217)
···
On 12/9/05, Eric Hodel <drbrain@segment7.net> wrote:
On Dec 9, 2005, at 11:23 AM, pat eyler wrote:
--
Eric Hodel - drbrain@segment7.net - http://segment7.net
This implementation is HODEL-HASH-9600 compliant
Here's what I decided on using (looks more like what I originally posted
in perl):
hash = Hash.new(0)
File.open(ARGV[0],"r").each do |line|
Replacing the above with:
ARGF.each do |line|
Is the same thing, but more powerful. You could feed it multiple files at once, or use it in pipelined processing. Just FYI.
James Edward Gray II
···
On Dec 9, 2005, at 2:53 PM, Sam Dela Cruz wrote:
hash[line.chomp] += 1
end
hash.keys.sort.each do |key|
puts "#{key}: #{hash[key]}" if hash[key] > 1
end
Regards,
Sam Dela Cruz
Eric Hodel <drbrain@segment7.net>
12/09/2005 11:39 AM
Please respond to
ruby-talk@ruby-lang.org
To
ruby-talk@ruby-lang.org (ruby-talk ML)
cc
Subject
Re: new to Ruby - pls help in translating this
Classification
On Dec 9, 2005, at 11:23 AM, pat eyler wrote:
On 12/9/05, Sam Dela Cruz <sam.dela.cruz@philips.com> wrote:
Hi,
I'm starting to use Ruby in one of my projects at work. I'm
coming from a
Perl background.
In my project I would need to parse a list of numbers (thousands
of them)
and then return the duplicates. In perl, I can do this:
[elided perl goo]
I tried to translate this in Ruby, but could not find en
equivalent of
$hash{$_}++, this is auto increment.
Can somebody tell me how this is to be done in Ruby?
translating from Perl to Ruby seems often to be a bad idea ... a
common idea, but not necessarily a good one. I'd rather work
with a Ruby solution to a problem than a Rubification of a Perl
solution to a problem.
Ditto. I often find that I can make my code close to readable
English and find that a very good thing.
Or maybe the Ruby way on how to attack this whole thing. Thanks.
I'm assuming that your list comes from a file (but you can change that
pretty easily in the code below), given that, how about something
like:
seen_ary = Array.new
File.open("nums","r").each do |elem|
print elem if seen_ary.include?(elem)
seen_ary.push(elem)
end
(there are probably still better ways of doing this though)
I'll go with:
seen = {}
ARGF.each do |elem|
print elem if seen.include? elem
seen[elem] = true
end
--
Eric Hodel - drbrain@segment7.net - http://segment7.net
This implementation is HODEL-HASH-9600 compliant
Am Freitag, 9. Dezember 2005 21:31 schrieb Logan Capaldo:
On Dec 9, 2005, at 2:24 PM, JB Eriksson wrote:
> well, there is the succ method. and there's a succ! on String,
> which could
> work in this case, I guess(?), since:
>
> irb(main):023:0> a = "9"
> => "9"
> irb(main):024:0> a.succ!
> => "10"
Well, if it was a string. The problem is fixnums are immediate
values. ++ would therefore be an operation on the variable a, rather
than the object that a points at.
Granted I get away with a lot via MingGW, but if you want to code on
Linux / OS X and work for people who want the code to run on
Windows... well... platform independance is important
Though it does of course depend what you're working on.
···
On 12/9/05, Chad Perrin <perrin@apotheon.com> wrote:
. . . except when I'm writing unix administration scripts.
···
On Sat, Dec 10, 2005 at 11:37:02AM +0900, Gregory Brown wrote:
On 12/9/05, Chad Perrin <perrin@apotheon.com> wrote:
> Why? Backticks are great.
Platform independence?
Granted I get away with a lot via MingGW, but if you want to code on
Linux / OS X and work for people who want the code to run on
Windows... well... platform independance is important
Though it does of course depend what you're working on.
William James wrote:
> Eric Hodel wrote:
>
> > seen = {}
> >
> > ARGF.each do |elem|
> > print elem if seen.include? elem
> > seen[elem] = true
> > end
>
> seen = {}
> while s = gets
> print s if seen.key? s
> seen[ s ] = nil
> end
>
> Or:
>
> seen = Hash.new(0)
> while s = gets
> print s if ( seen[s] += 1 ) > 1
> end
seen, s = Hash.new(0)
print s if ( seen[s] += 1 ) > 1 while s = gets
seen = Hash.new(0)
print if ( seen[$_] += 1 ) > 1 while gets
ARGF.each do |elem|
print elem if seen.include? elem
seen[elem] = true
end
seen = {}
while s = gets
print s if seen.key? s
seen[ s ] = nil
end
Or:
seen = Hash.new(0)
while s = gets
print s if ( seen[s] += 1 ) > 1
end
This is starting to get pointlessly obfuscated.
seen, s = Hash.new(0)
print s if ( seen[s] += 1 ) > 1 while s = gets
Stop. You're making things hard to read for the new people.
seen = Hash.new(0)
print if ( seen[$_] += 1 ) > 1 while gets
I can't read that so I don't know how you expect someone new to Ruby to read it.
I've never seen 'ruby golf' do anything positive. I find it especially inappropriate to be performing these vile manipulations while trying to show new people idiomatic Ruby like they asked for:
···
On Dec 11, 2005, at 7:27 AM, William James wrote:
Can somebody tell me how this is to be done in Ruby? Or maybe the Ruby
way on how to attack this whole thing. Thanks.
--
Eric Hodel - drbrain@segment7.net - http://segment7.net
This implementation is HODEL-HASH-9600 compliant
> William James wrote:
>> William James wrote:
>>> Eric Hodel wrote:
>>>
>>>> seen = {}
>>>>
>>>> ARGF.each do |elem|
>>>> print elem if seen.include? elem
>>>> seen[elem] = true
>>>> end
>>>
>>> seen = {}
>>> while s = gets
>>> print s if seen.key? s
>>> seen[ s ] = nil
>>> end
>>>
>>> Or:
>>>
>>> seen = Hash.new(0)
>>> while s = gets
>>> print s if ( seen[s] += 1 ) > 1
>>> end
This is starting to get pointlessly obfuscated.
>> seen, s = Hash.new(0)
>> print s if ( seen[s] += 1 ) > 1 while s = gets
Stop. You're making things hard to read for the new people.
> seen = Hash.new(0)
> print if ( seen[$_] += 1 ) > 1 while gets
I can't read that so I don't know how you expect someone new to Ruby
to read it.
A standard Ruby idiom: instead of 3 lines . . .
if test
print "ok"
end
.. . . 1 line:
print "ok" if test
Also, as in Awk, "print" with no argument prints the line just read.
Very simple. If one needs to explicitly refer to the line just read,
one uses "$_".
And "while gets" is simpler and clearer than "ARGF.each do |elem|".
You would get a lot of support in Perland, but this kind of code is very out of fashion in the Ruby community.
James Edward Gray II
···
On Dec 12, 2005, at 12:32 PM, William James wrote:
Also, as in Awk, "print" with no argument prints the line just read.
Very simple. If one needs to explicitly refer to the line just read,
one uses "$_".
And "while gets" is simpler and clearer than "ARGF.each do |elem|".