http://www.perlmonks.org?node_id=115835


in reply to Sorting an array of strings by number

There is more than one path to take here:

  1. Zero-pad your numbers, so generate them with
    my $padded=sprintf("%08.3f",39.452);
    You can do this while reading your data:
    while (<>){ split /:/; $_[0]=sprintf("%08.3f", $_[0]); push @data, join ":", @_; }
  2. Or you can sort numerically. This requires you to extract the numbers and sort on them with <=> (see perlop), like
    sort{ $a <=> $b} @numbers;
    . You can write a sub for the extraction:
    sort{extract( $a ) <=> extract( $b )} @lines; sub extract{ $a = shift; split /:/, $a; $_[0]; }
  3. It's better to extract your numbers, and use them as keys in a hash, and work with a list of sorted keys:
    my %hash; while(<>){ my ($key, $data) = split( /:/, $_, 2 ); $hash{ $key } = $data; } print "Sorted!:\n\n", join "|", sort {$a <=> $b} keys %hash;
  4. .... many more paths to come up with

HTH,

Jeroen
"We are not alone"(FZ)
(code untested, you'll get the idea)

Update
Albannach is right of course. Still, if you have quite some data, a hash-lookup is more efficient. And more scalable, as you can tie your hash onto a database, e.g. To prevent that double-count problem, add a check in for the key, if a double, add a counter or something.

$key .= ':001' if defined $hash{$key}; $key++ while defined $hash{$key};

Replies are listed 'Best First'.
Re: Re: Sorting an array of strings by number
by Albannach (Monsignor) on Oct 01, 2001 at 17:27 UTC
    Note that in your option 3 the unique keys of the hash will be likely to clobber some data as the anonymonk specified that the first value is price in his problem. Hashes are great for many reasons but this example is easily and simply addressed by a simple numerical sort so unless there is reason to need to search the data by price, and a certainty of unique pricing, I'll go with one of your first two options.

    --
    I'd like to be able to assign to an luser