Can Perl6 cmp two strings case insensitively?

Perl 6 doesn't currently have that as an option, but it is a very mutable language so let's add it.

Since the existing proto doesn't allow named values we have to add a new one, or write an only sub.
(That is you can just use the multi below except with an optional only instead.)

This only applies lexically, so if you write this you may want to mark the proto/only sub as being exportable depending on what you are doing.

proto sub infix:<leg> ( \a, \b, *% ){*}

multi sub infix:<leg> ( \a, \b, :ignore-case(:$i) ){
  $i

  ?? &CORE::infix:<leg>( fc(a) , fc(b) )
  !! &CORE::infix:<leg>(    a  ,    b  )
}
say 'a' leg 'A';     # More
say 'a' leg 'A' :i;  # Same
say 'a' leg 'A' :!i; # More

say 'a' leg 'A' :ignore-case; # Same

Note that :$i is short for :i( $i ) so the two named parameters could have been written as:
:ignore-case( :i( $i ) )

Also I used the sub form of fc() rather than the method form .fc because it allows the native form of strings to be used without causing autoboxing.


If you want a "dictionary" sort order, @timotimo is on the right track when they suggest collate and coll for sorting.

Use collate() on anything listy to sort it. Use coll as an infix operator in case you need a custom sort.

$ perl6
To exit tyype 'exit' or '^D'
> <a Zp zo zz ab 9 09 91 90>.collate();
(09 9 90 91 a ab zo Zp zz)
> <a Zp zo zz ab 9 09 91 90>.sort: * coll *;
(09 9 90 91 a ab zo Zp zz)

You can pass a code block to sort. If the arity of the block is one, it works on both elements when doing the comparison. Here's an example showing the 'fc' from the previous answer.

> my @a = <alpha BETA gamma DELTA>;
[alpha BETA gamma DELTA]
> @a.sort
(BETA DELTA alpha gamma)
> @a.sort(*.fc)
(alpha BETA DELTA gamma)

Tags:

Raku