Re: I need sorting help

[email protected] (Bruce Gray)
Newsgroups perl.perl6.users
Message-ID <[email protected]>

> On Mar 4, 2024, at 15:55, ToddAndMargo via perl6-users <[email protected]> wrote:


--snip--

> $ raku -e '.say for <bk10 bk34 bk2 bk1>.sort(*.split(/\d+/, :kv).map({ (try .Numeric) // $_}).List)'
> bk1
> bk2
> bk10
> bk34
> 
> Yippee!
> 
> 
> tony@rn6:/home/linuxutil1$ raku -e '.say for <bk10 bk34 bk2 bk1>.sort: { .comb(/ \d+ | \D+ /) .map({ .Int // .self })};'
> bk1
> bk10
> bk2
> bk34
> 
> Rats!  Thank for trying anyway!
> 
> -- 
> love, todd


Wow! Very subtle trap with Seq!

The short answer is: Just add `.cache`:
raku -e '.say for <bk10 bk34 bk2 bk1>.sort: { .comb(/ \d+ | \D+ /).map({ .Int // .self }).cache };' 
bk1
bk2
bk10
bk34

When the elements that `.sort` is sorting are of type List or Array, the sorting happens one slot at a time; the sort happens on element [0] of each List, and ties are settled by [1] (or [2] if [1] are also a tie, etc). This enables `.sort` to behave very intuitively (after the shock wears off).

I did not detect the problem by eye, but when I broke it down on the commandline I see that Seq objects are being created by `.comb` and `.map`.
Objects of Seq type can only be read *once*, so the multiple reads that `.sort` needs would not play well with Seq. It does not matter whether you convert the numbers to a Numeric type (which you did correctly in the `.map`), they are still part of a Seq.

The .cache method turns the Seq into a List, and the sort behaves as you intended.
https://docs.raku.org/routine/cache


-- 
Hope this helps,
Bruce Gray (Util of PerlMonks)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.