0

I have an array in perl that contains about 200 indexes that are for a csv file. It likes like the lines below:

46.9234784633993,Springwood Drive,Naples,FL
89.7786182217159,W 8th St,Lakeland,FL

I want to sort them by that number before the first comma. I tried using just sort, but sometimes the numbers get into the hundreds and thousands and it just sorts all those in the 1's. Then a numerical sort doesnt like it since they are not numerical entries

I tried this

my @sortedDistances = sort{ $a <=> $b }(@completedDistances);
and
my @sortedDistances = sort(@completedDistances);
2
  • Then a numerical sort doesn't like it since they are not numerical entries ???? Commented Jan 18, 2013 at 22:04
  • Show us what you have tried. We can't tell from your description what you have done wrong. Edit your question to include the failing code. Then, describe what exactly is not working. What happened when you tried it? Did you get incorrect results? Did you get no results? If the results were incorrect, what made them incorrect? What were you expecting instead? Did you get any correct results? If so, what were they? Don't make us guess. Commented Jan 18, 2013 at 22:11

4 Answers 4

5

This is a possible solution, try if it works:

open FILE, "<", $ARGV[0] or die $!;
my @sorted =
    map { join ",", @{$_} }
    sort { $a->[0] <=> $b->[0] }
    map { [ split /,/ ] } <FILE>;
close FILE;
say join "\n", @sorted;

EDIT: changed colon to comma

Sign up to request clarification or add additional context in comments.

1 Comment

This is actually the correct answer. It might be worth noting that using something like split /,/, $_, 2 (with third argument) is more efficient, as it limits the number of regex matches performed. (Also, chomping and then joining with a newline is hilarious; print @sorted should work as well)
4

The classic Schwartzian Transform, which I think @sdir intended to code, would look like this

use strict;
use warnings;

my @sorted =  map $_->[0],
              sort { $a->[1] <=> $b->[1] }
              map [$_, /([^,]+)/], <>;

print for @sorted;

1 Comment

If the last unsorted csv line doesn't end with \n and that line is not the last after the sort, two lines will print together, e.g., "46.9234784633993,Springwood Drive,Naples,FL89.7786182217159,W 8th St,Lakeland,FL". Perhaps map {chomp; [$_, /([^,]+)/]} <>; and then print join "\n", @sorted; would help.
1

normal sort to the rescue

sort -t, -n -k1,1 file.cvs

-t, means separate at comman

-n or -g numerical sort

-k1,2 use column 1 to 2 see -t

man sort

3 Comments

@sdir: no, but the pure guy mentioned 'sort' him self, and used right it can save you a lot of time writing funny perl oneliners, - and debugging them.
True that. I definitely would have done it with shell sort, too. But perl is more fun (and I use that 'oneliner' actually alot). No offense itended btw.
Sorry it would have worked but I need to keep it perl now. I didn't know this needs to be done automatically 35000 times
-1

I would write a sort function to get the first item from each and then do the comparison on the items. It would be of the form:

sub sortStuff($$)
{
  my ($a) = split(',',$_[0]);
  my ($b) = split(',',$_[1]);

  return ( $a <=> $b ) ;
}

and then call the subroutine as part of the call to sort:

@sortedArray = sort sortStuff @array;

It will sort on the number and ignore the rest of the items on the line.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.