Merge pull request #38611 from volth/nat-sort

lib: add naturalSort
This commit is contained in:
Jörg Thalheim 2018-04-08 22:44:15 +01:00 committed by GitHub
commit 0fe11dbedd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 23 additions and 2 deletions

View file

@ -74,7 +74,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 ["10.46.133.149" "10.5.16.62" "10.54.16.25"]
=> ["10.5.16.62" "10.46.133.149" "10.54.16.25"]
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: