Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Re: Sort hash with values

by sundialsvc4 (Abbot)
on Jun 24, 2013 at 12:52 UTC ( #1040426=note: print w/ replies, xml ) Need Help??


in reply to Sort hash with values

I think that I see the problem.   Ordinarily, you would be able to iterate over something like foreach ( sort keys(%IP_store) ) ..., but IP-address strings of varying lengths won’t sort correctly as strings.

The sort verb does allow for a subroutine to be specified, which must return a value that is less than, equal or greater than zero as appropriate, so we do have the mechanism by which to sort the strings the way we want:   as a left-to-right hierarchical collection of four integers.   So, let’s define a separate sub to do this ... something along these (untested) lines:

# 'sort' COMPARISON FUNCTION FOR IP-ADDRESSES. sub ip_compare { # GRAB THE TWO ARGUMENTS PASSED BY 'SORT' my ($a, $b) = @_; # SPLIT THE IP-ADDRESSES INTO FOUR =STRINGS= BY # THE PERIOD CHARACTER. my ($a1, $a2, $a3, $a4) = split('\.', @$a); my ($b1, $b2, $b3, $b4) = split('\.', @$b); # TYPECAST EACH COMPONENT AS INTEGERS, THEN # USE INTEGER '<=>' OPERATOR TO COMPARE NUMBERS. # USE A STACK OF SHORT-CIRCUIT '||' OPS WHICH WILL # STOP AT (AND RETURN) THE FIRST NON-ZERO RESULT # IN THE CHAIN. return (int($a1) <=> int($b1)) || (int($a2) <=> int($b2)) || (int($a3) <=> int($b3)) || (int($a4) <=> int($b4)); }

And I would put that subroutine (when debugged), with its comments, into my program.   There are many ways to write it:   this one is reasonably clear.

Now we can do something like sort (ip_compare, keys(%ip_addr)), or something like that, and it should work.   You iterate over the returned list of keys and retrieve the values from the hash by key.


Comment on Re: Sort hash with values
Download Code
Replies are listed 'Best First'.
Re^2: Sort hash with values
by AnomalousMonk (Abbot) on Jun 24, 2013 at 17:53 UTC
    # SPLIT THE IP-ADDRESSES INTO FOUR =STRINGS= BY # THE PERIOD CHARACTER. my ($a1, $a2, $a3, $a4) = split('.', @$a);

    The split built-in function does not use single-quotes around a  /PATTERN/ argument to 'meta-quote' the argument: the  '.' in the above really is trying to split on "any character except newline". Use  '\.' to split on a literal period.

    >perl -wMstrict -le "my $s = 'a.bb.ccc.d'; ;; my @ra = split '.', $s; print 'naked dot'; printf qq{ '$_'} for @ra; print '@ra elements: ', scalar @ra; ;; @ra = split '\.', $s; print 'escaped dot'; printf qq{ '$_'} for @ra; " naked dot @ra elements: 0 escaped dot 'a' 'bb' 'ccc' 'd'

      Excellent point.   Thank you.   I have updated the post accordingly.   But, even so, my post consisted of extemporaneous coding.   I did not separately test it to see if it would actually run.   I made it only as an illustration of the essential idea, “implementation left as an exercise to the reader.”

        ... extemporaneous coding ... “implementation left as an exercise to the reader.”

        I understand. But given my perception of the relative inexperience of Rahul Gupta WRT Perl coding, and of the relatively subtle nature of the bug and its manifestation, I wanted to be very explicit about the problen I saw.

        I did not separately test it to see if it would actually run.

        My own experience with the excellent advice I customarily dispense is that it always works — except when I don't test it, and then, for some reason, it never works! That's why I always try to provide a "complete input-execution-output experience", usually in the form of some kind of command-line capture. That way, there's no question about execution conditions, code, data, etc... Caveat praeceptor.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (12)
As of 2015-07-08 08:40 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (98 votes), past polls