[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

new to Ruby - pls help in translating this

Sam Dela Cruz

12/9/2005 6:49:00 PM

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:

##### Perl code
%hash = {};
while (<>)
{
chomp;
$hash{$_}++;
}

foreach my $key (sort keys %hash)
{
print "$key: $hash{$key}\n" if ($hash{$key} > 1);
}

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? Or maybe the Ruby
way on how to attack this whole thing. Thanks.

Regards,
Sam
44 Answers

James Gray

12/9/2005 6:54:00 PM

0

On Dec 9, 2005, at 12:48 PM, Sam Dela Cruz 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:
>
> ##### Perl code
> %hash = {};
> while (<>)
> {
> chomp;
> $hash{$_}++;
> }
>
> foreach my $key (sort keys %hash)
> {
> print "$key: $hash{$key}\n" if ($hash{$key} > 1);
> }
>
> I tried to translate this in Ruby, but could not find en equivalent of
> $hash{$_}++, this is auto increment.

See if this gets you going:

seen = Hash.new(0)
ARGF.each_line { |line| seen[line.strip] += 1 }

seen.each { |key, value| puts key if value > 1 }

James Edward Gray II


Dan Diebolt

12/9/2005 7:08:00 PM

0

use the following to initiate your hash:

h=Hash.new(0)

and this to increment on each key:

h[key] = h[key] + 1


---------------------------------
Yahoo! Shopping
Find Great Deals on Holiday Gifts at Yahoo! Shopping

Michael Fellinger

12/9/2005 7:14:00 PM

0

Hey,

after looking at your code (wich was a bit hard, since i don't speak perl) - i
came up with following solution, that doesn't seem very ruby-esque but works
well for me.
I'm sure someone brings the code down to one line, but i'm a bit too lazy to
try that :)

file = File.open(ARGV[0]).readlines
h = {}
file.each{|x| (h[x].nil?) ? (h[x] = 1) : (h[x] = h[x]+=1)}
h.each_pair{|k,v| puts "#{k.strip} appears #{v} times" if v >= 2}

Am Freitag, 9. Dezember 2005 19:48 schrieb Sam Dela Cruz:
> 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:
>
> ##### Perl code
> %hash = {};
> while (<>)
> {
> chomp;
> $hash{$_}++;
> }
>
> foreach my $key (sort keys %hash)
> {
> print "$key: $hash{$key}\n" if ($hash{$key} > 1);
> }
>
> 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? Or maybe the Ruby
> way on how to attack this whole thing. Thanks.
>
> Regards,
> Sam

Logan Capaldo

12/9/2005 7:16:00 PM

0


On Dec 9, 2005, at 1:48 PM, Sam Dela Cruz 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:
>
> ##### Perl code
> %hash = {};
> while (<>)
> {
> chomp;
> $hash{$_}++;
> }
>
> foreach my $key (sort keys %hash)
> {
> print "$key: $hash{$key}\n" if ($hash{$key} > 1);
> }
>

hash = Hash.new { |h, k| h[k] = 0 }

while gets
$_.chomp!
hash[$_] += 1
end

> I tried to translate this in Ruby, but could not find en equivalent of
> $hash{$_}++, this is auto increment.

Ruby has no auto-increment since variables are more like labels on
objects than containers for objects and numbers are generally
immutable in ruby.
IOW:
x = 3
x++ in ruby would be like typing 3++ which doesn't make sense really.

> 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.
>
> Regards,
> Sam



pat eyler

12/9/2005 7:23:00 PM

0

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.

> 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)

>
> Regards,
> Sam
>


--
thanks,
-pate
-------------------------


mrkode@gmail.com

12/9/2005 7:25:00 PM

0

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"


On 12/9/05, Logan Capaldo <logancapaldo@gmail.com> wrote:
>
>
> On Dec 9, 2005, at 1:48 PM, Sam Dela Cruz 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:
> >
> > ##### Perl code
> > %hash = {};
> > while (<>)
> > {
> > chomp;
> > $hash{$_}++;
> > }
> >
> > foreach my $key (sort keys %hash)
> > {
> > print "$key: $hash{$key}\n" if ($hash{$key} > 1);
> > }
> >
>
> hash = Hash.new { |h, k| h[k] = 0 }
>
> while gets
> $_.chomp!
> hash[$_] += 1
> end
>
> > I tried to translate this in Ruby, but could not find en equivalent of
> > $hash{$_}++, this is auto increment.
>
> Ruby has no auto-increment since variables are more like labels on
> objects than containers for objects and numbers are generally
> immutable in ruby.
> IOW:
> x = 3
> x++ in ruby would be like typing 3++ which doesn't make sense really.
>
> > 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.
> >
> > Regards,
> > Sam
>
>
>

Dan Diebolt

12/9/2005 7:31:00 PM

0

>variables are more like labels on objects than containers for objects

There is something very fundamental about what you are saying here but I don't quite understand. Could you elaborate on this with perhaps an example?


---------------------------------
Yahoo! Shopping
Find Great Deals on Holiday Gifts at Yahoo! Shopping

Wilson Bilkovich

12/9/2005 7:37:00 PM

0

Or, something else to think about.. shamelessly borrowed from this
mailing list a month or so ago..
Wrapped in lame 'gets' code to let you play with it at the command
line. I presume you'd actually do something cooler with STDIN or a
filename.

class Array
def dups
h, d = {}, []; each{|e| h[e] ? (d << h.delete(e)) : (h[e] = e)}; d
end
end
numbers = []
while n = STDIN.gets.chomp
break if n == ''
numbers << n
end
puts numbers.dups

I love reopening Array.

--Wilson.

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:
>
> ##### Perl code
> %hash = {};
> while (<>)
> {
> chomp;
> $hash{$_}++;
> }
>
> foreach my $key (sort keys %hash)
> {
> print "$key: $hash{$key}\n" if ($hash{$key} > 1);
> }
>
> 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? Or maybe the Ruby
> way on how to attack this whole thing. Thanks.
>
> Regards,
> Sam
>


Eric Hodel

12/9/2005 7:39:00 PM

0

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://se...
This implementation is HODEL-HASH-9600 compliant

http://trackmap.rob...




MenTaLguY

12/9/2005 7:55:00 PM

0

Quoting Sam Dela Cruz <sam.dela.cruz@philips.com>:

> 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:
>
> ##### Perl code
> %hash = {};
> while (<>)
> {
> chomp;
> $hash{$_}++;
> }
>
> foreach my $key (sort keys %hash)
> {
> print "$key: $hash{$key}\n" if ($hash{$key} > 1);
> }
>
> I tried to translate this in Ruby, but could not find en
> equivalent of $hash{$_}++, this is auto increment.

It also autovivifies the hash element, but Ruby doesn't have
autovivification.

Here's a nearly literal translation to Ruby (the main difference is
that gets is like <STDIN>, not <>):

hash = {}
while gets
chomp
hash[$_] ||= 0 # vivify
hash[$_] += 1 # increment
end

for key in hash.keys.sort
print "#{key}: #{hash[key]}\n" if hash[key] > 1
end

Here's the same thing in a slightly more Ruby-ish style ($_ is
normally avoided in Ruby, even though it's available):

hash = Hash.new( 0 )
$stdin.each do |line|
hash[line.chomp] += 1
end

hash.keys.sort.each do |key|
puts "#{key}: #{hash[key]}" if hash[key] > 1
end

Here, we create a hash whose default value for uninitialized
elements is 0, rather than nil (nil is like Perl's undef). Note
that a default value you provide this way is used directly for
every element; it is not copied.

Note also that line.chomp is not the same thing as chomp $line in
Perl; line.chomp returns a new string rather than modifying the
existing one. The exact equivalent of Perl's chomp $line would be
line.chomp!.

-mental