From 25c2fd80b15d601936351e8340974b5c39e84681 Mon Sep 17 00:00:00 2001 From: volth Date: Sun, 8 Apr 2018 10:55:06 +0000 Subject: [PATCH 1/2] lib: add naturalSort --- lib/default.nix | 2 +- lib/lists.nix | 23 ++++++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/lib/default.nix b/lib/default.nix index cbe0a0ba21b5..3fce15c6ec9f 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -72,7 +72,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 diff --git a/lib/lists.nix b/lib/lists.nix index 424d2c57f556..f386cf5e2324 100644 --- a/lib/lists.nix +++ b/lib/lists.nix @@ -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 ["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. Example: From 3f8c9106ea7cbe32cb9a95c6e952dca90387a0ca Mon Sep 17 00:00:00 2001 From: volth Date: Sun, 8 Apr 2018 13:54:39 +0000 Subject: [PATCH 2/2] lib: add naturalSort (move the example IPs to private space) --- lib/lists.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/lists.nix b/lib/lists.nix index f386cf5e2324..5ec97f5a07f3 100644 --- a/lib/lists.nix +++ b/lib/lists.nix @@ -417,8 +417,8 @@ rec { 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 ["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" ] */