It is funny, I started with a Schwartzian transform, but thought to myself "why 
not simplify the code?".
Not realizing it is a performance gain.
I have always thought of it only as a means to do more complicated sorts.

Thanks for making that clear.

Funny, once more, is that one member of this list contacted me off-list asking 
if it is possible to sort only _some_ of the fields in a pre-defined order.
It is possible. We could assing a sort key to those fields.
And make use of the Schwartzian Transform!

We have some 5XX fields that we want to see in a certain order, not defined 5XX 
fields will show up after our choosen ones and will be sorted according to our 
current locale (national settings).

The used prefix "500" serves double purposes:
1) to make the defined 5xx-fields sort before undefined 5xx fields
2) to make 5xx fields sort correctly among other fields (0XX - 9XX)

my %sortkey = (
    "516" => "500" . "001",    
    "538" => "500" . "002",
    "546" => "500" . "003",
    "500" => "500" . "004",
    "536" => "500" . "005",
    "530" => "500" . "006",
    "520" => "500" . "007",
    "505" => "500" . "008",
    "506" => "500" . "009",
    "540" => "500" . "010",
    "504" => "500" . "011",
    "533" => "500" . "012",
    "534" => "500" . "013",
    #"500" => "500" . "999", # If "500" had not been defined above, we'd put it 
here to make 500 appear as first tag after the defined tags
    );

@{$record->{_fields}} =  map { $_->[0] }
     sort  { $a->[1] cmp $b->[1] }
     map   { [$_, defined $sortkey{$_->{_tag}} ? lc($sortkey{$_->{_tag}}) : 
lc($_->{_tag})] } @{$record->{_fields}};


If field "500" had not been assigned a sort key, we would see that field 
erroneously sort before any other 5XX field.
To prevent that we could add a definition for 500 as the last one
    i.e. "500" => "500" . "999"


If we had wanted the defined fields to sort AFTER not defined fields, we'd 
choosen another prefix
    like "516" => "599" . "001"

Leif

-----Ursprungligt meddelande-----
Från: Brad Baxter [mailto:[EMAIL PROTECTED]
Skickat: den 13 maj 2005 19:30
Till: perl4lib (E-mail)
Ämne: Re: MARC::Record ordering of fields


On Fri, 13 May 2005, Leif Andersson wrote:
> How would you do to re-order the fields in a MARC::Record-record?
>
> I just needed that kind of thing and after some struggeling came up with:
>
> @{$record->{_fields}} =
>      sort  {
>              lc($a->{_tag}) cmp lc($b->{_tag})
>            }
>      @{$record->{_fields}};
>
>
> It seems to work, but I am interested in how others would address
> the same problem.
>
> Leif

I think it's not likely to matter very much in this case, unless you
need to do this to thousands of records, but ideally you'd probably
want to do a Schwartzian Transform, or map-sort-map operation:

@{$record->{_fields}} =
    map  { $_->[0] }
    sort { $a->[1] cmp $b->[1] }
    map  { [ $_, lc($_->{_tag}) ] }
    @{$record->{_fields}};

This decreases the number of lc calls and _tag retrievals to once per
field.

Regards,

Brad

Reply via email to