Let's split it up a bit:

You have a hash, %saw. Individual elements of a hash are accessed via $hash{key}. If you append the postfix ++ operator to it, it looks like $saw{key}++, which increments the hash element by one.

Now, what does that do?

The grep iterates over the whole array @in, sets $_ to each element and then executes the code, in our case the expression !$saw{$_}++. If the expression returns a true value, grep keeps the array element in its result, otherwise it's discarded.

Now, when a key in %saw does not already exists, the code sets $saw{key} to 1 (incrementing by one from undef), and then returns the negation of the previous hash value (undef is false, so it returns true). So, if the hash key did not yet exist in the hash, the array element is put into @out.

The other case is that the hash key already exists in the hash. Then $saw{$_} returns a number greater than zero, which is interpreted as true, and the negation of that is false, so the (duplicate) array element in @in is discarded.

This method is a nice and easy way (once you understand it) to get a unique list of elements in an array while retaining the order. There are other methods, like using the keys of %saw:

undef %saw; $saw{$_}++ for @in; @out = keys %saw;

This code puts the same elements into @out, but you lose the order.

I don't remember if it was quicker, but there also is the non-looped version:

undef %saw; @saw{@in} = (1) x @in; @out = keys %saw;

In reply to Re: What does !$saw{$_}++ means by Corion
in thread What does !$saw{$_}++ means by nwkcmk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.