From 8f99c3953c6bea7b23ec04c60a658dd11ea8bdb4 Mon Sep 17 00:00:00 2001 From: Matt Sturgeon Date: Mon, 19 Aug 2024 00:45:47 +0100 Subject: [PATCH] lib/util: add `groupListBySize` Splits up a list into many sub-lists based on the given max-size. e.g. ```nix groupListBySize 2 [ 1 2 3 4 5 ] => [ [ 1 2 ] [ 3 4 ] [ 5 ] ] ``` --- lib/helpers.nix | 1 + lib/utils.nix | 19 +++++++++++++++++++ tests/lib-tests.nix | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+) diff --git a/lib/helpers.nix b/lib/helpers.nix index 86ac4346..030ca873 100644 --- a/lib/helpers.nix +++ b/lib/helpers.nix @@ -71,6 +71,7 @@ let concatNonEmptyLines emptyTable enableExceptInTests + groupListBySize hasContent ifNonNull' listToUnkeyedAttrs diff --git a/lib/utils.nix b/lib/utils.nix index 43b22fce..7c548f68 100644 --- a/lib/utils.nix +++ b/lib/utils.nix @@ -147,4 +147,23 @@ rec { ${string} EOF ''; + + # Split a list into a several sub-list, each with a max-size of `size` + groupListBySize = + size: list: + reverseList ( + foldl' ( + lists: item: + let + first = head lists; + rest = drop 1 lists; + in + if lists == [ ] then + [ [ item ] ] + else if length first < size then + [ (first ++ [ item ]) ] ++ rest + else + [ [ item ] ] ++ lists + ) [ ] list + ); } diff --git a/tests/lib-tests.nix b/tests/lib-tests.nix index 7eb3ab3c..abaecb23 100644 --- a/tests/lib-tests.nix +++ b/tests/lib-tests.nix @@ -333,6 +333,47 @@ let "MIxEd" ]; }; + + testGroupListBySize = { + expr = { + empty = helpers.groupListBySize 5 [ ]; + "5/5" = helpers.groupListBySize 5 (lib.genList lib.id 5); + "13/5" = helpers.groupListBySize 5 (lib.genList lib.id 13); + }; + expected = { + empty = [ ]; + "5/5" = [ + [ + 0 + 1 + 2 + 3 + 4 + ] + ]; + "13/5" = [ + [ + 0 + 1 + 2 + 3 + 4 + ] + [ + 5 + 6 + 7 + 8 + 9 + ] + [ + 10 + 11 + 12 + ] + ]; + }; + }; }; in if results == [ ] then