Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Sorting @lines

by kanabrian (Initiate)
on Oct 10, 2002 at 19:55 UTC ( [id://204308]=perlquestion: print w/replies, xml ) Need Help??

kanabrian has asked for the wisdom of the Perl Monks concerning the following question:

I need to sort array which contains numeric values which contain "." ie. I need to sort @lines which contains (124.43.adsf.ca, 235.23.aer.ca, 100.34.asdm.ca) to @sortedlines which is (100.34.asdm.ca, 124.43.adsf.ca, 235.23.aer.ca)

Replies are listed 'Best First'.
Re: Sorting @lines
by Mr. Muskrat (Canon) on Oct 10, 2002 at 20:02 UTC

    So just sort it ;)

    my @lines = ('124.43.adsf.ca', '235.23.aer.ca', '100.34.asdm.ca'); # c +reate the unsorted array my @sorted = sort @lines; # create the sorted array for (@sorted) { print "$_\n"; } # display

    This displays:
    100.34.asdm.ca
    124.43.adsf.ca
    235.23.aer.ca

      Emm... realized where my error lies. Thanks. Initially I tried what you said did not work. But I know why. i was reading each files from directory. Due to logic error, I did not obtain a sorted list. I was able to fix. I thought it was due to the "." in the numbers. Thanks.
Re: Sorting @lines
by JaWi (Hermit) on Oct 10, 2002 at 19:58 UTC
    This sounds like a job for a Schwartzian Transform! I'm too tired to give you any example code at the moment... Sorry!
    Update: What a sip of beer can do! Here you go:
    use strict; use Data::Dumper; my @data = qw( 124.43.adsf.ca 235.23.aer.ca 100.34.asdm.ca ); my @sorted = map { $_->[ 0 ] } sort { $a->[1] cmp $b->[1] } map { [$_, /(\d+\.\d)/] } @data;

    Greets,

    -- JaWi

    "A chicken is an egg's way of producing more eggs."

Re: Sorting @lines
by Zaxo (Archbishop) on Oct 10, 2002 at 20:17 UTC

    I'm curious why you want that ordering, but never mind. Here is a Schwartian transform method with priority ordering.

    my @sorted_lines = map {join '.', @$_} sort { $a->[0] <=> $b->[0] || $a->[1] <=> $b->[1] || $a->[2] cmp $b->[2] || $a->[3] cmp $b->[3]} map { [split '.'] } @lines;

    Reading right-to-left, each element of @lines is transformed to a reference to an array of the dot seperated values. Then the transformed array is sorted with left-to-right priority in the elements. Only if a comparison of the zero-th elements comes up equal, is the one-th elements compared. That is from the short-circuit behavior of the || operator. Finally the sorted array is turned back into its original form with the join map.

    Those transformations are done to avoid many expensive calls to split and the associated creation of temporary variables.

    After Compline,
    Zaxo

Re: Sorting @lines
by dws (Chancellor) on Oct 10, 2002 at 20:07 UTC
    If all of the values are of the same shape that you indicate(a dotted quad with two numeric and two string elements), something like
    @sorted = map { $_->[0] } sort { $a->[1] <=> $b->[1] || $a->[2] <=> $b->[2] || $a->[3] cmp $b->[3] || $a->[4] cmp $b->[4] } map { [ $_, split(/\./, $_) ] } @lines;
    should do the trick. This applies a Schwartzian transform to build and sort an intermediate representation, with the value being sorted pulled out of the hat by the top map. Note that the first two elements are sorted numerically, and the second two are sorted as alphabetically.

Re: Sorting @lines
by Anonymous Monk on Oct 11, 2002 at 00:32 UTC
    @sortedlines = map{(split)[1]} sort map{sprintf"%09d%09d%s%s %s",(split/\./)[0..3],$_} @lines;
      That will break if any of the elements have spaces in them. Probably not very likely, but a safer way to write a GRT is:
      my @sorted = map{(split(/\0/))[1]} sort map{sprintf"%09d%09d%s%s\0%s",(split/\./)[0..3],$_} @lines;

      -Blake

Re: Sorting @lines
by =sjs= (Initiate) on Oct 10, 2002 at 23:37 UTC
    #!/usr/local/bin/perl -w use strict; my @stuff = qw (124.43.adsf.ca 235.23.aer.ca 100.34.asdm.ca); my %hash = map { $_, m{(\d+(?:\.\d+)*)} } @stuff; @stuff = sort {$hash{$a} <=> $hash{$b}} keys %hash; print join "\n", @stuff;
    Use a hash to cache your numbered values part and sort based on the keys.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://204308]
Approved by JaWi
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (4)
As of 2024-04-19 05:48 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found