New to Ruby - pls help in translating this

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

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

···

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.

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

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 :slight_smile:

file = File.open(ARGV[0]).readlines
h = {}
file.each{|x| (h.nil?) ? (h = 1) : (h = h+=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

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.

···

On Dec 9, 2005, at 1:48 PM, Sam Dela Cruz 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.

Regards,
Sam

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)

···

On 12/9/05, Sam Dela Cruz <sam.dela.cruz@philips.com> wrote:

Regards,
Sam

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

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

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

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 = {};

That doesn't do what you think it does. In Perl, the {} here
will create a hash reference, which is a scalar datatype.
You're assigning it to a %hash variable, which accepts LIST
data. This ends up being the same as:

  %hash = ( {} );

Which creates a hash named %hash, stringifies the hash reference
and uses it as a key, and without any additional values to work
with, uses undef as a value for the key.

To see this in action:

    use Data::Dumper;
    my %hash = {};
    print Dumper( \%hash );

Compare to:

    use Data::Dumper;
    my %hash = ();
    print Dumper( \%hash );

Yes. You want to use parentheses.

while (<>)
{
    chomp;
        $hash{$_}++;
}

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

HTH,
Tim Hammerquist

···

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

Or, in keeping with the DRY and KISS principles I humbly submit the lowly shell command, uniq, instead of Ruby at all:

$ uniq -d <file>

e.g.

/tmp corey$ cat foo
1
2
3
4
/tmp corey$ uniq -d foo
1
3
/tmp corey$

Although, it was interesting to see the diversity of Ruby solutions.

Corey

···

On Dec 9, 2005, at 10:48 AM, 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.
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

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

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

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

···

On Dec 9, 2005, at 11:23 AM, pat eyler wrote:

On 12/9/05, Sam Dela Cruz <sam.dela.cruz@philips.com> wrote:

--
Eric Hodel - drbrain@segment7.net - http://segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com

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

That is far too complicated and impossible to read. I think we should be giving new people examples of how to make code clear and expressive.

numbers =
while n = STDIN.gets.chomp

$ echo -n '' | ruby -e 'p STDIN.gets'
nil

  break if n == ''
  numbers << n
end
puts numbers.dups

I love reopening Array.

I like clear, expressive code: [ruby-talk:169927]

···

On Dec 9, 2005, at 11:37 AM, Wilson Bilkovich wrote:

--
Eric Hodel - drbrain@segment7.net - http://segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com

Tim,

Sorry and yes you are right. This block of code came from a big program I
have. I had to modify some stuff to simplify before sending this out to
the mailing list but forgot to change the bracket - { to parentheis - (.
Originally I was using a reference to a hash. So sorry for those who got
confused. Thanks for pointing this out.

Sam

Tim Hammerquist <penryu@saiyix.ath.cx>
12/09/2005 02:04 PM
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

List-Owner: <mailto:ruby-talk-admin@ruby-lang.org>
List-Help: <mailto:ruby-talk-ctl@ruby-lang.org?body=help>
List-Unsubscribe: <mailto:ruby-talk-ctl@ruby-lang.org?body=unsubscribe>

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 = {};

That doesn't do what you think it does. In Perl, the {} here
will create a hash reference, which is a scalar datatype.
You're assigning it to a %hash variable, which accepts LIST
data. This ends up being the same as:

  %hash = ( {} );

Which creates a hash named %hash, stringifies the hash reference
and uses it as a key, and without any additional values to work
with, uses undef as a value for the key.

To see this in action:

    use Data::Dumper;
    my %hash = {};
    print Dumper( \%hash );

Compare to:

    use Data::Dumper;
    my %hash = ();
    print Dumper( \%hash );

Yes. You want to use parentheses.

while (<>)
{
    chomp;
        $hash{$_}++;
}

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

HTH,
Tim Hammerquist

···

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

Or, in keeping with the DRY and KISS principles I humbly submit the
lowly shell command, uniq, instead of Ruby at all:

$ uniq -d <file>

e.g.

/tmp corey$ cat foo
1
1
2
3
3
4
/tmp corey$ uniq -d foo
1
3
/tmp corey$

but it doesn't always work:
pate@linux:~/scratch> cat nums
1
2
3
4
4
5
6
5
7
pate@linux:~/scratch> uniq -d files
uniq: files: No such file or directory
pate@linux:~/scratch> uniq -d nums
4
pate@linux:~/scratch>

you need to do:
pate@linux:~/scratch> sort -n nums | uniq -d
4
5

but if this is supposed to be part of a larger program, shell
is probably the wrong way to go about it.

···

On 12/9/05, Corey Jewett <corey@syntheticplayground.com> wrote:

Although, it was interesting to see the diversity of Ruby solutions.

Corey

On Dec 9, 2005, at 10:48 AM, 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.
> 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

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

I'll go with:

seen = {}

ARGF.each do |elem|
  print elem if seen.include? elem
  seen[elem] = true
end

Thanks, this is how ruby should look like!

here is another one (i like it a bit more
functional style):

quantities = Hash.new{|h, k| h[k]=0}
ARGF.each{|l| quantities[l.chomp.to_i] += 1}
puts quantities.delete_if{|k, v| v <= 1}.keys

cheers

Simon

Well basically, all variables in ruby are references (or pointers, whatever you want to call them), but they are actually even less "clingy" than that.

maybe an example will help

x = "a string"
y = x # this doesn't do something like x.copy nor is it even equalivalent to typing y = "a string"
          # it more like saying
         # x =
         # "a string"
         # y =

y.upcase! #=> "A STRING"
x #=> "A STRING"

Just think of varibles as a way to refer to a memory address
If x and y "contain" anythjing it is a memory address and they both have the same memory.

Basically they are pointers. Except when they aren't. Fixnums for instance are stored as values. As are symbols. I think I might have over complicated this. Maybe someone else can explain it better.

···

On Dec 9, 2005, at 2:31 PM, Dan Diebolt wrote:

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

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.

···

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"

Thank you all. I learned a little bit more ruby. And yes, I want to do
things the Ruby way, but I just can't help to think perl still and then
translate to ruby. This is very similar to when I came to the U.S. and
all of a sudden I have to talk in English, I still think in my original
language(Tagalog) and then translate it in English and it doesn't always
come up the way English speakers would say it. But I get the point
accross. But yes, going back to Ruby, I'd like to learn things the Ruby
way and so far I have good things to say about Ruby. One, it being so
readable, and second I think it is easier to learn especially the OOP part
of it. In perl OOP is a big hurdle.

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

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

···

On Dec 9, 2005, at 11:23 AM, pat eyler wrote:

On 12/9/05, Sam Dela Cruz <sam.dela.cruz@philips.com> wrote:

--
Eric Hodel - drbrain@segment7.net - http://segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com