Re: pint: Elizabeth, sort list???

[email protected] (Elizabeth Mattijsen)
Newsgroups perl.perl6.users
Message-ID <[email protected]>
> On 3 Mar 2024, at 03:32, ToddAndMargo via perl6-users <[email protected]> wrote:
> 
>> On 3/2/24 05:13, Elizabeth Mattijsen wrote:
>>> <afoo12 afoo2>.sort(*.split(/\d+/, :kv).map({ (try .Numeric) // $_}).List)
> 
>> Hi Elizabeth,
>> It works perfectly.  Thank you!
>> I have no idea why, I will ask you in another post
> Would you take apart your sort piece by piece and explain
> each part?

Actually, the expression can be refined a bit:

say <afoo12 afoo2>.sort(*.split(/\d+/, :v).map({ (try .Int) // $_}).List)

Sort works by using `cmp` semantics by default.

If `cmp` is called on two lists, it will `cmp` each element and return the result of the first comparison that did not produce `Same`.

If you call `sort` with a Callable that takes only one argument, it is taken as the producer of the actual values that will be compared, basically doing a Schwartzian transform under the hood.

A whatever code (which is what we specified here) produces a Callable with a single argument.  So we'll be doing a Schwartzian transform under the hood.

The `split` splits the value (each element in the list) on any set of Numeric characters (`\d+`), *but* also produces the strings that were split on (`:v`). (The previous version had .kv, but that just produces more identical entries in the list, which only will make comparisons slower).

The resulting values from the `split` are then mapped to an integer value (if possible: `(try .Int)` and if that fails, just returns the value (`// $_`).  (The previous version had `.Numeric`, which will also work, but since `\d+` can only produce integers, it's an extra unnecessary step).

Then convert the `.Seq` that is produced by the `.map` to a `List`.  Otherwise we'd be comparing `Seq` objects, and the semantics of those are undefined.

So for `"afoo12" cmp "afoo2"`, we will be doing `("afoo", 12) cmp ("afoo", 2)`.  Which would do: `"afoo" cmp "afoo"`, which produces `Same`, and then do `12 cmp 2`, which will return `More`, and thus will cause swapping the order of <afoo12 afoo2>.


Hope that made sense!
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.