in reply to Sorting issues

Ok, they say "never assume", but I'm gonna suggest a different answer than the others given so far, based on the following assumption: Aren't your arrays actually triplets of coordinates, each triplet ($x[$i], $y[$i], $z[$i]) representing a point in 3D?

If that is the case, might I suggest a change in data structures?
my @points; # This will add one point (the first one in your arrays # above) to another type of data structure. my %this_point = {x => 0, y => 0, z => 25}; push @points, \%this_point; # Do this for as many points as you have. You can # adapt the method you use to fill your three arrays # to create this kind of data structure using the # example above.
That would allow you to refer to the X component of a point $i as:
$points[$i]->{x}

Then, the sorting becomes a bit easier:
# Sort by z first, then sort by x for each point @points = sort { $a->{x} <=> $b->{x} } sort { $a->{z} <=> $b->{z} } @points;
(note: untested, but should give you the idea)

I find this data structure more intuitive, since the triplets of coordinates, which are related (they form a point in 3D), are actually together in the data structure, whereas in the arrays in your original post they are separated.

Replies are listed 'Best First'.
Re: Re: Sorting issues
by runrig (Abbot) on Jan 09, 2004 at 18:17 UTC
    I find this data structure more intuitive

    Just be aware that you'll be using 3-4 times the memory for this data structure. For a relatively small number of points its fine, but you can squeeze more points into memory if you just use plain arrays like the OP has.

    BTW, your sort does not work. You can't do sequential sorts and expect it to still be sorted by the previous order (although it sometimes might appear to work, it doesn't always).

      > Just be aware that you'll be using 3-4 times the memory for this data structure.

      Thanks for pointing that out, I didn't know.
      update: Now that I think of it, I find it unfortunate that better design would carry such a high cost... But I know, that's Perl: equivalent speed at the cost of higher resource usage.

      > You can't do sequential sorts and expect it to still be sorted by the previous order

      Hmmm, didn't think about that. For my personal knowledge, then, how would you sort by one criteria and then by another? Something similar to the above?
      sort { $a->{z} <=> $b->{z} || $a->{x} <=> $b->{x} } @points;
      ???

        Yes, that sort will work. In the original example, the second sort simply undid the results of your first sort.

        In your new sort, the part after '||' will only happen if $a->{z} == $b->{z}, so it works like you want it to.

•Re: Re: Sorting issues
by merlyn (Sage) on Jan 09, 2004 at 18:12 UTC
    There's no promise that sort is stable there (and it wasn't, depending on the version of Perl that you are using). Other solutions in this thread do the trick with a single sort: please look at those.

    -- Randal L. Schwartz, Perl hacker
    Be sure to read my standard disclaimer if this is a reply.

      merlyn: Agreed, my "combination sort" isn't the greatest. But the OP can combine the sort from other posts with the idea about changing the way his data is structured from my post to solve his problem.

      My main point was about the data structure's design more closely modeling the data itself. But thanks for your comment anyways, it's very true.

      update: subject line