FAQ

--- David Blevins wrote:
perl -nle 'print if !$seen{$_}++'
The dash n (-n) puts the command 'print if !$seen{$_}++' in a while
(<>) { ... } loop. So we get:

while (<>) {
print if !$seen{$_}++
}

$seen{$_}

Tries to lookup the line in the hash of lines we've already seen.

$seen{$_}++

This is a complete guess, I can't seem to find anything like this in
the 'Programming Perl' book.
It's just a postfix increment on the value in %seen as looked up using
$_ as the key. You've got the idea.
It seems that if you say:

$seen{$_} = 1;

it causes the key to be added to the hash with the value 1, which is
true in boolean context.
So, if the key (line) wasn't previously seen, line"

$seen{$_}

might return a 0 or "false" to indicate it wasn't found. Then the
line

$seen{$_}++

might take that 0/"false", increment it by one turning it to 1/"true"
causing the key/$_/"line" to be added with a value of 1/"true". If
the $_/"line" were already seen, it would have been added initially
with a value 1/"true"; the ++ in this situation would just increment
the value to 2,3,4...n, all of which are "true" values.
There you go.
!$seen{$_}

Might negate the 1/"true" return of looking up a key that previously
existed in the hash, causing the

print

statement to execute, which is just short for

print STDOUT $_;
Good. The leading ! makes it boolean, so it returns 1 or ''.
So how close am I and where can I read about this?
lol -- you kind of have to look up the pieces. ;o]
Or maybe there's something in the FAQ's?
perl -pe '$_ x= !$seen{$_}++'
This would bypass the need for the print statement, but I'm not sure
how the '$_ x= ' in the statement works.
This is the one that tickled me most.
I parsed it in another post. ;o]
$seen{$_} ||= print OUT while <IN>;
This is tons of fun! Dying to know the answer!
= is an "or-equal" -- it assigns the right-hand argument to the
left-hand argument if the current value of the left-hand argument is
boolean false. "$a ||= 1" assigns 1 to $a if $a was '',0, or undef.
Otherwise it leaves it alone.

Since print returns a bool, and while <IN> assigns to $_ (which is
print()'s default), it prints the line just read and assigns 1 to
$seen{$_} if $seen{$_} had no value, but if $seen{$_} already has a
value, it just returns that in a void context -- a no-op. =o)
Then it reads the next line of <IN>.

I love Perl. =o)

Of course, writing readable code is always a good idea, but explaining
*tight* code is a great learning experience! lol!

__________________________________________________
Do You Yahoo!?
Make international calls for as low as $.04/minute with Yahoo! Messenger
http://phonecard.yahoo.com/

Search Discussions

Discussion Posts

Previous

Follow ups

Related Discussions

Discussion Navigation
viewthread | post
posts ‹ prev | 9 of 16 | next ›
Discussion Overview
groupbeginners @
categoriesperl
postedJul 30, '01 at 6:15p
activeJul 30, '01 at 9:40p
posts16
users6
websiteperl.org

People

Translate

site design / logo © 2022 Grokbase