lib: add naturalSort

This commit is contained in:
volth 2018-04-08 10:55:06 +00:00
parent 35eddf5ef1
commit 25c2fd80b1
2 changed files with 23 additions and 2 deletions

View file

@ -72,7 +72,7 @@ let
inherit (lists) singleton foldr fold foldl foldl' imap0 imap1 inherit (lists) singleton foldr fold foldl foldl' imap0 imap1
concatMap flatten remove findSingle findFirst any all count concatMap flatten remove findSingle findFirst any all count
optional optionals toList range partition zipListsWith zipLists optional optionals toList range partition zipListsWith zipLists
reverseList listDfs toposort sort compareLists take drop sublist reverseList listDfs toposort sort naturalSort compareLists take drop sublist
last init crossLists unique intersectLists subtractLists last init crossLists unique intersectLists subtractLists
mutuallyExclusive; mutuallyExclusive;
inherit (strings) concatStrings concatMapStrings concatImapStrings inherit (strings) concatStrings concatMapStrings concatImapStrings

View file

@ -1,7 +1,9 @@
# General list operations. # General list operations.
{ lib }: { lib }:
with lib.trivial; with lib.trivial;
let
inherit (lib.strings) toInt;
in
rec { rec {
inherit (builtins) head tail length isList elemAt concatLists filter elem genList; inherit (builtins) head tail length isList elemAt concatLists filter elem genList;
@ -409,6 +411,25 @@ rec {
then compareLists cmp (tail a) (tail b) then compareLists cmp (tail a) (tail b)
else rel; else rel;
/* Sort list using "Natural sorting".
Numeric portions of strings are sorted in numeric order.
Example:
naturalSort ["disk11" "disk8" "disk100" "disk9"]
=> ["disk8" "disk9" "disk11" "disk100"]
naturalSort ["46.133.149.113" "5.16.62.13" "54.16.25.114"]
=> ["5.16.62.13" "46.133.149.113" "54.16.25.114"]
naturalSort ["v0.2" "v0.15" "v0.0.9"]
=> [ "v0.0.9" "v0.2" "v0.15" ]
*/
naturalSort = lst:
let
vectorise = s: map (x: if isList x then toInt (head x) else x) (builtins.split "(0|[1-9][0-9]*)" s);
prepared = map (x: [ (vectorise x) x ]) lst; # remember vectorised version for O(n) regex splits
less = a: b: (compareLists compare (head a) (head b)) < 0;
in
map (x: elemAt x 1) (sort less prepared);
/* Return the first (at most) N elements of a list. /* Return the first (at most) N elements of a list.
Example: Example: