Q:

How to reverse sort an array, sort starts on the end of the line

I have a bunch of addresses in an LDAP database and want to remove a street. For this I have to remove the houses first. LDAP database output is not sorted
my @x1=("c=NL",
        "nr=1,s=Dam,a=AMS,c=NL",
        "s=Dam,a=AMS,c=NL",
        "a=AMS,c=NL",
        "nr=3,s=Plein,a=AMS,c=NL",
        "s=Plein,a=AMS,c=NL",
        "nr=2,s=Dam,a=AMS,c=NL"   );

Before we can remove 's=Dam' we have to remove 'nr=1,s=Dam,a=AMS,c=NL' and "nr=2,s=Dam,a=AMS,c=NL" first, before we can remove "s=Dam,a=AMS,c=NL"
The direction I choose was sorting the lines from the end to the front, so first "c=NL", then "a=AMS" and so on. And then running through the array if it contained "s=Dam,a=AMS,c=NL".
As a result should look,like:

    'nr=2,s=Dam,a=AMS,c=NL'
    'nr=1,s=Dam,a=AMS,c=NL'
    's=Dam,a=AMS,c=NL'

I added Data::Dumper in the code to show what happens
    my @x1=("c=NL",
            "nr=1,s=Dam,a=AMS,c=NL",
            "s=Dam,a=AMS,c=NL",
            "a=AMS,c=NL",
            "nr=3,s=Plein,a=AMS,c=NL",
            "s=Plein,a=AMS,c=NL",
            "nr=2,s=Dam,a=AMS,c=NL"   );
    print Data::Dumper->Dump([\@x1],['*x1']);

    my @x2=split( "\n", reverse join ("\n", @x1));
    print Data::Dumper->Dump([\@x2],['*x2']);

    my @x3=sort @x2;
    print Data::Dumper->Dump([\@x3],['*x3']);

    my @x4=split( "\n", reverse join ("\n", @x3));
    print Data::Dumper->Dump([\@x4],['*x4']);

    foreach (@x4) {
      # if matches from the rear: "s=Dam,a=AMS,c=NL", do stuff
    }

this is the result
@x1 = (
        'c=NL',
        'nr=1,s=Dam,a=AMS,c=NL',
        's=Dam,a=AMS,c=NL',
        'a=AMS,c=NL',
        'nr=3,s=Plein,a=AMS,c=NL',
        's=Plein,a=AMS,c=NL',
        'nr=2,s=Dam,a=AMS,c=NL'
     ); @x2 = (
        'LN=c,SMA=a,maD=s,2=rn',
        'LN=c,SMA=a,nielP=s',
        'LN=c,SMA=a,nielP=s,3=rn',
        'LN=c,SMA=a',
        'LN=c,SMA=a,maD=s',
        'LN=c,SMA=a,maD=s,1=rn',
        'LN=c'
      ); @x3 = (
        'LN=c',
        'LN=c,SMA=a',
        'LN=c,SMA=a,maD=s',
        'LN=c,SMA=a,maD=s,1=rn',
        'LN=c,SMA=a,maD=s,2=rn',
        'LN=c,SMA=a,nielP=s',
        'LN=c,SMA=a,nielP=s,3=rn'
      ); @x4 = (
        'nr=3,s=Plein,a=AMS,c=NL',
        's=Plein,a=AMS,c=NL',
        'nr=2,s=Dam,a=AMS,c=NL',
        'nr=1,s=Dam,a=AMS,c=NL',
        's=Dam,a=AMS,c=NL',
        'a=AMS,c=NL',
        'c=NL'
      );

Can this code be improved, so the code can be more readable. 

A:

sub reverse_terms { join ',', reverse split /,/, $_[0] }

my @sorted =
   map reverse_terms($_),
   reverse sort
   map reverse_terms($_),
   @unsorted;

or
use Sort::Key qw( rkeysort );

my @sorted = rkeysort { join ',', reverse split /,/ } @unsorted;

The above solutions transform
s=Dam,a=AMS,c=NL
nr=1,s=Dam,a=AMS,c=NL

into
c=NL,a=AMS,s=Dam
c=NL,a=AMS,s=Dam,nr=1

Then, they sort the transformed strings in descending order. This causes the children to appear before the parents.
c=NL,a=AMS,s=Dam,nr=1
c=NL,a=AMS,s=Dam

Finally, it's just a question of transforming the string back (or returning the original string, in the case of rkeysort).

