Hello shankonit, and welcome to the Monastery!

The statement my %seen creates an empty hash. Then the foreach loop works as follows: On the first iteration, $element is 3 (the first element of the array @array). The if statement looks up the hash value $seen{$element}, i.e. $seen{3}, but of course doesn’t find it because the hash is empty. But the code says to increment (++) that element, so an important feature of Perl called autovivification comes into play: the hash element $seen{3} is created, with an initial value of undef, which is silently interpreted as 0 (zero) and incremented to 1. But because the postincrement form is used (i.e., $x++ instead of ++$x), the value of the expression $seen{$element}++ is the value it had before the increment, which in this case is undef. And since undef is false, negating this false value with not makes it true, so the if clause is entered and $element is pushed onto the array @ordered.

Likewise for the subsquent iterations in which $element is equal to 4 and then to 1. But when $element is set to 4 a second time, the expression $seen{$element} is already present in the hash, and has the value 1, which is true. Negating it makes it false, so the if clause is not entered. The result is that each element of @array is added only once to the new array @ordered.

The point of this is presumably to show how to convert an array with duplicates: @array = (3, 4, 1, 4, 7, 7, 4, 1, 3, 8); into an array with the same elements but all duplicates removed: @ordered = (3, 4, 1, 7, 8). Unfortunately, the new array is misnamed: it isn’t “ordered,” it is rather an array of unique values. The code has nothing to do with ordering, only with the removal of duplicate elements.

Update 1: On autovivification, see the references in this node. On removing duplicates from an array, see How-can-I-remove-duplicate-elements-from-a-list-or-array of perlfaq4.

Update 2: On second thoughts, I think the hash %unordered and array @ordered have been so-named to highlight an important difference between the first technique and the second: namely, that the second preserves the order of the first occurrences of each element in the original array, whereas the first technique does not (because hashes, unlike arrays, are unordered).

Hope that helps,

Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,


In reply to Re: Understanding Perl context by Athanasius
in thread Understanding Perl context by shankonit

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.