in reply to Sorting an array of hashes with an exception

Just tell sort that if the RouteDistance is zero, it should use Distance. Note that the result is different to the one you gave.
#!/usr/bin/perl use warnings; use strict; my @ar = ( { ID => 3, Distance => 2.3, RouteDistance => 4.3 }, { ID => 2, Distance => 1.5, RouteDistance => 2.8 }, { ID => 5, Distance => 2.1, RouteDistance => 0 }, { ID => 1, Distance => 1.7, RouteDistance => 2.5 }, ); print $_->{ID}, "\n" for sort { ( $a->{RouteDistance} || $a->{Distance} ) <=> ( $b->{RouteDistance} || $b->{Distance} ) } @ar;

Upate : Fixed precedence.

لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

Replies are listed 'Best First'.
Re^2: Sorting an array of hashes with an exeption
by BrowserUk (Patriarch) on May 08, 2013 at 17:12 UTC

    That's not quite right.

    If one routedistance is 0 and the other not, you are comparing a routedistance with a distance, which is probably the cause of the disparity between your results and the OPs expectations.

    Something like this ought to do it:

    sort { $a->{routedistance} && $b->{routedistance} ? $a->{routedistance} <=> $b->{routedistance} : $a->{distance} <=> $b->{distance} } @ar;

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      Thanks. I misunderstood "for this hash" in the specification.
      لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
      BrowserUK you're the boss! It works great, thank you so much!

        In response to your /msg (it's easier to reply here than in a bunch of /msgs):

        I was wondering a little about your method you provided on my question regarding sort. It works just as I want but Im just curious about how its working. Im pretty new to Perl and I've not seen that kind of syntax berfore regarding ? and :

        Essentially, the conditional (or ternary) operator:boolean expr ? expr1 : expr2 is similar to if( boolean expr ) { expr1 } else { expr2 }, except that the former is an expression rather than a statement, and thus has a residual value once evaluated.

        In the case of the sort block:

        $a->{routedistance} && $b->{routedistance} ? $a->{routedistance} <=> $b->{routedistance} : $a->{distance} <=> $b->{distance}

        it says: if both routedistances are true (are non-zero), then return the result of comparing them; else return the result of comparing the two distances.

        See Conditional operator for (a little) more.


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re^2: Sorting an array of hashes with an exeption
by martin_87 (Initiate) on May 08, 2013 at 17:52 UTC
    Hi, thanks for the fast reply. The code which you provided gave me this result:

    ID = 5, Distance = 2.1, RouteDistance = 0
    ID = 1, Distance = 1.7, RouteDistance = 2.5
    ID = 2, Distance = 1.5, RouteDistance = 2.8
    ID = 3, Distance = 2.3, RouteDistance = 4.3

    It looks like it sorts by RouteDistance only here.

    The answer which BrowserUK provided works like a charm but I would like to know if you could provide an example where i add an argument as you where hinting about?
      It looks like it sorts by RouteDistance only here.
      Not really. Try setting Distance to 3.1 at ID 5.
      لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

        You're right, It doesn't only sort by RouteDistance. I didn't look long enough at the code, just the result. My bad.

        The result when changing ID: 5 with a distance of: 3.1 I get the following result:

        ID: 1 Distance: 1.7 RouteDistance: 2.5
        ID: 5 Distance: 3.1 RouteDistance: 0
        ID: 2 Distance: 1.5 RouteDistance: 2.8
        ID: 3 Distance: 2.3 RouteDistance: 4.3

        This is my excpected result but then again, it will not work in all cases :/

Re^2: Sorting an array of hashes with an exeption
by martin_87 (Initiate) on May 09, 2013 at 21:20 UTC
    Hi again, it does not change the output though? I'm still getting this as the result:

    ID: 5 Distance: 2.1 RouteDistance: 0
    ID: 1 Distance: 1.7 RouteDistance: 2.5
    ID: 2 Distance: 1.5 RouteDistance: 2.8
    ID: 3 Distance: 2.3 RouteDistance: 4.3

      Sure. 2.1 < 2.5, therefore 5 gets first. Try setting Distance of 5 to 3.1.
      لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

        I don't know how this solution can be at any help.

        Instead of changing distance I might aswell just change the RouteDistance to a bigger number and hope for the best..