about summary refs log tree commit diff
path: root/lib/lists.nix
diff options
context:
space:
mode:
authorvolth <volth@volth.com>2018-04-08 10:55:06 +0000
committervolth <volth@volth.com>2018-04-08 13:18:13 +0000
commit25c2fd80b15d601936351e8340974b5c39e84681 (patch)
tree3d37990174536be74a52d01010a9207f5689c44f /lib/lists.nix
parent35eddf5ef1aa420ff5a5984f5b449f510a3e4b90 (diff)
downloadnixlib-25c2fd80b15d601936351e8340974b5c39e84681.tar
nixlib-25c2fd80b15d601936351e8340974b5c39e84681.tar.gz
nixlib-25c2fd80b15d601936351e8340974b5c39e84681.tar.bz2
nixlib-25c2fd80b15d601936351e8340974b5c39e84681.tar.lz
nixlib-25c2fd80b15d601936351e8340974b5c39e84681.tar.xz
nixlib-25c2fd80b15d601936351e8340974b5c39e84681.tar.zst
nixlib-25c2fd80b15d601936351e8340974b5c39e84681.zip
lib: add naturalSort
Diffstat (limited to 'lib/lists.nix')
-rw-r--r--lib/lists.nix23
1 files changed, 22 insertions, 1 deletions
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: