my %orcish; my @sorted = map { # Final pass: restore the original datum, dropping # the extra stuff we added in the second pass: $$_[4] } sort { # Books whose author has a 'THIS BOOK FIRST' title are first: $$a[0] <=> $$b[0] # Within that, sort by author: or $$a[1] <=> $$b[1] # Within that, sort by whether it's THIS BOOK FIRST or not: or $$a[2] <=> $$b[2] # Within that, sort by the title, alphabetically: or $$a[3] <=> $$b[3] } map { # Second pass: gather enough info that sort can sort like we want: [$orcish{$$_{author}}, $$_{author}, ($$_{title} eq 'THIS BOOK FIRST'), $$_{title}, $_] } map { # First pass: take note of which authors have 'THIS BOOK FIRST': $orcish{$$_{author}}++ if $$_{title} eq 'THIS BOOK FIRST'; # But just pass through the data unmodified for now: $_ } @things_to_sort;