Sorting by email address is not as simple as just: sort @emails;

First is the easy bit:
If the domains are the same, we can just sort by the user

If the domains are not the same, we need to sort by the domain name. This is not as easy as sort(@domains) because we'd like to have them sorted firstly by TLD and then SLD and so on down the domain. That is: we put 'zebra.com.au' before 'aardvark.com' because .au should come before .com.

There might be an easier way to do this, but here is my solution for your comment and correction. All the email addresses in the example have been made up so don't think of spamming them OK?

CAVAET:

Names using a '!' should probably be sorted similar to the domain sorting. I believe some domains use a '!' in an email address to route the email within the organisation... can't remember though. (And should bob!alpha@domain come before bob@domain or alpha.domain?)
my @emails = qw/bob@a.com adam@cobra.com charles!adam@cobra.com ralph@beer.alpha.com bob@cobra.com rick@ignore.net.au fletcher@magma.com ballot@alpha.com.au biglug@magma.com matt@dc.com.au demo@beachfront.com media@ocular.com.au never@ocular.com.au/; print join("\n",@emails) . "\n\n"; @emails2 = sort by_email @emails; print join("\n",@emails2); sub by_email { # If they're the same, return 0 if ($a eq $b) { return 0 } # Split the two addresses into names and domains ($aname,$adomain) = split(/@/,$a); ($bname,$bdomain) = split(/@/,$b); # If the domains are the same, just compare the names if ($adomain eq $bdomain) { if ($aname gt $bname) { return 1 } else { return -1 } # No need to handle eq because its handled at the start of the + sub } # If the domains are different, we have to sort them else { # Split the domains into arrays at the periods @aparts = split(/\./,$adomain); @bparts = split(/\./,$bdomain); #Make the arrays equal length while ($#aparts < $#bparts) { unshift(@aparts,'') } while ($#aparts > $#bparts) { unshift(@bparts,'') } #loop backwards, comparing the parts as we go for ($i = $#aparts; $i >= 0; $i--) { return 1 if ($aparts[$i] gt $bparts[$i]); return -1 if ($aparts[$i] lt $bparts[$i]); } } # If we somehow get all the way through, send back a 0 # You might prefer to uncomment: # die("Sort by_email failed to find a comparisson. Panic."); return 0; }

In reply to Sort by Email Address by BigLug

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.