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
concatMap flatten remove findSingle findFirst any all count
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
mutuallyExclusive;
inherit (strings) concatStrings concatMapStrings concatImapStrings

View file

@ -1,7 +1,9 @@
# General list operations.
{ lib }:
with lib.trivial;
let
inherit (lib.strings) toInt;
in
rec {
inherit (builtins) head tail length isList elemAt concatLists filter elem genList;
@ -409,6 +411,25 @@ rec {
then compareLists cmp (tail a) (tail b)
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.
Example: