Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can Perl6 cmp two strings case insensitively?

Tags:

raku

I am doing a sort and would like to control the cmp of alpha values to be case insensitive (viz. https://perl6.org/archive/rfc/143.html).

Is there some :i adverb for this, perhaps?

like image 405
p6steve Avatar asked Aug 03 '18 18:08

p6steve


People also ask

Is Perl Eq case sensitive?

Numerical Operator (E.g: eq = equal, gt = greater than). Perl's string comparison is case-sensitive.


3 Answers

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.

like image 129
Brad Gilbert Avatar answered Oct 16 '22 23:10

Brad Gilbert


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)
like image 32
daotoad Avatar answered Oct 17 '22 00:10

daotoad


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)
like image 7
Coke Avatar answered Oct 16 '22 23:10

Coke