Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Re^7: What does 'next if $hash{$elem}++;' mean?

by blazar (Canon)
on Feb 25, 2006 at 08:51 UTC ( [id://532749]=note: print w/replies, xml ) Need Help??


in reply to Re^6: What does 'next if $hash{$elem}++;' mean?
in thread What does 'next if $hash{$elem}++;' mean?

If I print from within the subroutines it returns a text file that is ridiculously large and contains many repeated rows. The subroutine is supposed to be preventing repeated rows.

OMG!!! I can't believe what I'm reading! you've been asking this very question tenths of times in at least two threads in a variety of clumsy ways. A question that is actually and reasonably a FAQ and whose answer may be easily spotted by intelligent use of perldoc -q!

So you keep asking the same questions round and round seemingly failing to understand that Perl, like any other language, is made up of syntactical elements that will create a working program when suitably assembled together. This requires... Surprise! Surprise! a knowledge of at least the basic, elementary syntax and semantics of the language. You can happily ask for a piece of code and ignore its internals, provided you make sure there won't be side-effects, but you have to be aware at least of what you're feeding it and what you'll get. Indeed this is called the blackbox approach.

If one would come here and say "I'm not a Perl programmer, I just need to hack a tiny script for once and never touch Perl again", I think a lot of people would be happy to supply him with ready-made code, unless there are good reasons not to do so (e.g. the original script is malicious code and/or the OP is after malicious action). But if evidence is that one, like you, will have to routinely program in Perl, then it's ridiculous to demand doing so without actually knowing Perl. One can know little Perl and go on nicely. He won't use the most advanced/nice/elegant/fancy/performant/efficient features, but he will get the job done. Insisting on trying to program in Perl, or in any other language for what it matters, prior to have become familiar with the basics is just like trying to write fictional prose without knowing the language it is to be written in: it is plainly idiotic stupid!

Taking into account your reluctance to put into practice the single piece of advice that mostly everyone has been giving you thus far, and the one that would solve the vast majority of your problems, that is to become acquainted with that minimal amount of Perl that you may learn from any introductory tutorial, I do not see much point in giving you further answers, and in fact I'm trying one last time, then I won't spend any more of my time and efforts to try to help you.


"Your" sub

our $rcListHash = sub { my %seen = (); my @uniq = (); foreach my $item (@data) { push @uniq, $item unless $seen{$item} ++; } print OUTPUT @uniq; # Instead of return @uniq; };

was originally made to return the unique entries in the global @data. With your modification it prints to OUTPUT... surprise! the unique entries in the global @data. If that is not what you wanted, then yes: you're using it in a wrong way!!

(Incidentally you have no reason to assign to a package variable the subref - you can be content with a plain sub declaration.)

To be sincere, besides that you want some code that will print to some file the unique lines from some other file, or something similar, it is very hard to understand what you really want. Because if what you want is:

  • exactly that, then
    #!/usr/bin/perl use strict; use warnings; my %saw; while (<>) { print if !$saw{$_}++; } __END__
    is one such program;
  • an equivalent one-liner, then
    perl -ne 'print if !$saw{$_}++'
    will do;
  • a golfed version of the one-liner, then
    perl -pe'$_ x=!$$_++'
    is the best I could get;
  • a sub that returns the unique elements of a list passed to it, then
    sub uniq { my %saw; grep !$saw{$_}++, @_; }
    is one way to implement it;
  • a sub that trusts the first argument to be a filheandle opened for writing and writes into it the unique elements of the remaining ones, then
    sub uniq { my ($out, %saw)=shift; print $out grep !$saw{$_}++, @_; }
    is the obvious adaptation;
  • a sub that can be called multiple times and in its whole life cycle only returns unique elements from the joint list of all the arguments it is passed each time, then
    { my %saw; sub { grep !$saw{$_}++, @_ } }
    shows you that it is enough to move a variable in an outer lexical scope;
  • code that provides means to create several independent instances of similar actions, then the term "instance" should ring a bell and tell you:object! object! like the following minimal example
    #!/usr/bin/perl -l use strict; use warnings; package Uniq; sub new { bless my $self={}, shift } sub check { my $self=shift; grep !$self->{$_}++, @_; } package main; my $u=Uniq->new; my $u2=Uniq->new; print for $u->check(qw/foo bar baz/); print for $u->check(qw/foo barr baz/); print "--"; print for $u2->check(qw/foo barr baz/); __END__
    examplifies.

So all, in all, what is it that makes any of these solutions, and all the other ones that other people suggested, impossible to adapt to your needs?!?

Replies are listed 'Best First'.
Re^8: What does 'next if $hash{$elem}++;' mean?
by turo (Friar) on Feb 26, 2006 at 17:06 UTC

    What a nightmare! ... Win attacks back and forth with the same question!!!! arrg.

    Great post blazar!

    perl -Te 'print map { chr((ord)-((10,20,2,7)[$i++])) } split //,"turo"'

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://532749]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (6)
As of 2024-03-29 09:56 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found