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