Loading lib/default.nix +1 −1 Original line number Diff line number Diff line Loading @@ -89,7 +89,7 @@ let recurseIntoAttrs dontRecurseIntoAttrs cartesianProduct cartesianProductOfSets mapCartesianProduct updateManyAttrsByPath; inherit (self.lists) singleton forEach foldr fold foldl foldl' imap0 imap1 concatMap flatten remove findSingle findFirst any all count ifilter0 concatMap flatten remove findSingle findFirst any all count optional optionals toList range replicate partition zipListsWith zipLists reverseList listDfs toposort sort sortOn naturalSort compareLists take drop sublist last init crossLists unique allUnique intersectLists Loading lib/lists.nix +49 −1 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ { lib }: let inherit (lib.strings) toInt; inherit (lib.trivial) compare min id warn; inherit (lib.trivial) compare min id warn pipe; inherit (lib.attrsets) mapAttrs; in rec { Loading Loading @@ -333,6 +333,54 @@ rec { */ imap1 = f: list: genList (n: f (n + 1) (elemAt list n)) (length list); /** Filter a list for elements that satisfy a predicate function. The predicate function is called with both the index and value for each element. It must return `true`/`false` to include/exclude a given element in the result. This function is strict in the result of the predicate function for each element. This function has O(n) complexity. Also see [`builtins.filter`](https://nixos.org/manual/nix/stable/language/builtins.html#builtins-filter) (available as `lib.lists.filter`), which can be used instead when the index isn't needed. # Inputs `ipred` : The predicate function, it takes two arguments: - 1. (int): the index of the element. - 2. (a): the value of the element. It must return `true`/`false` to include/exclude a given element from the result. `list` : The list to filter using the predicate. # Type ``` ifilter0 :: (int -> a -> bool) -> [a] -> [a] ``` # Examples :::{.example} ## `lib.lists.ifilter0` usage example ```nix ifilter0 (i: v: i == 0 || v > 2) [ 1 2 3 ] => [ 1 3 ] ``` ::: */ ifilter0 = ipred: input: map (idx: elemAt input idx) ( filter (idx: ipred idx (elemAt input idx)) ( genList (x: x) (length input) ) ); /** Map and concatenate the result. Loading lib/tests/misc.nix +27 −0 Original line number Diff line number Diff line Loading @@ -63,8 +63,10 @@ let hasAttrByPath hasInfix id ifilter0 isStorePath lazyDerivation length lists listToAttrs makeExtensible Loading Loading @@ -651,6 +653,31 @@ runTests { expected = ["b" "c"]; }; testIfilter0Example = { expr = ifilter0 (i: v: i == 0 || v > 2) [ 1 2 3 ]; expected = [ 1 3 ]; }; testIfilter0Empty = { expr = ifilter0 (i: v: abort "shouldn't be evaluated!") [ ]; expected = [ ]; }; testIfilter0IndexOnly = { expr = length (ifilter0 (i: v: mod i 2 == 0) [ (throw "0") (throw "1") (throw "2") (throw "3")]); expected = 2; }; testIfilter0All = { expr = ifilter0 (i: v: true) [ 10 11 12 13 14 15 ]; expected = [ 10 11 12 13 14 15 ]; }; testIfilter0First = { expr = ifilter0 (i: v: i == 0) [ 10 11 12 13 14 15 ]; expected = [ 10 ]; }; testIfilter0Last = { expr = ifilter0 (i: v: i == 5) [ 10 11 12 13 14 15 ]; expected = [ 15 ]; }; testFold = let f = op: fold: fold op 0 (range 0 100); Loading Loading
lib/default.nix +1 −1 Original line number Diff line number Diff line Loading @@ -89,7 +89,7 @@ let recurseIntoAttrs dontRecurseIntoAttrs cartesianProduct cartesianProductOfSets mapCartesianProduct updateManyAttrsByPath; inherit (self.lists) singleton forEach foldr fold foldl foldl' imap0 imap1 concatMap flatten remove findSingle findFirst any all count ifilter0 concatMap flatten remove findSingle findFirst any all count optional optionals toList range replicate partition zipListsWith zipLists reverseList listDfs toposort sort sortOn naturalSort compareLists take drop sublist last init crossLists unique allUnique intersectLists Loading
lib/lists.nix +49 −1 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ { lib }: let inherit (lib.strings) toInt; inherit (lib.trivial) compare min id warn; inherit (lib.trivial) compare min id warn pipe; inherit (lib.attrsets) mapAttrs; in rec { Loading Loading @@ -333,6 +333,54 @@ rec { */ imap1 = f: list: genList (n: f (n + 1) (elemAt list n)) (length list); /** Filter a list for elements that satisfy a predicate function. The predicate function is called with both the index and value for each element. It must return `true`/`false` to include/exclude a given element in the result. This function is strict in the result of the predicate function for each element. This function has O(n) complexity. Also see [`builtins.filter`](https://nixos.org/manual/nix/stable/language/builtins.html#builtins-filter) (available as `lib.lists.filter`), which can be used instead when the index isn't needed. # Inputs `ipred` : The predicate function, it takes two arguments: - 1. (int): the index of the element. - 2. (a): the value of the element. It must return `true`/`false` to include/exclude a given element from the result. `list` : The list to filter using the predicate. # Type ``` ifilter0 :: (int -> a -> bool) -> [a] -> [a] ``` # Examples :::{.example} ## `lib.lists.ifilter0` usage example ```nix ifilter0 (i: v: i == 0 || v > 2) [ 1 2 3 ] => [ 1 3 ] ``` ::: */ ifilter0 = ipred: input: map (idx: elemAt input idx) ( filter (idx: ipred idx (elemAt input idx)) ( genList (x: x) (length input) ) ); /** Map and concatenate the result. Loading
lib/tests/misc.nix +27 −0 Original line number Diff line number Diff line Loading @@ -63,8 +63,10 @@ let hasAttrByPath hasInfix id ifilter0 isStorePath lazyDerivation length lists listToAttrs makeExtensible Loading Loading @@ -651,6 +653,31 @@ runTests { expected = ["b" "c"]; }; testIfilter0Example = { expr = ifilter0 (i: v: i == 0 || v > 2) [ 1 2 3 ]; expected = [ 1 3 ]; }; testIfilter0Empty = { expr = ifilter0 (i: v: abort "shouldn't be evaluated!") [ ]; expected = [ ]; }; testIfilter0IndexOnly = { expr = length (ifilter0 (i: v: mod i 2 == 0) [ (throw "0") (throw "1") (throw "2") (throw "3")]); expected = 2; }; testIfilter0All = { expr = ifilter0 (i: v: true) [ 10 11 12 13 14 15 ]; expected = [ 10 11 12 13 14 15 ]; }; testIfilter0First = { expr = ifilter0 (i: v: i == 0) [ 10 11 12 13 14 15 ]; expected = [ 10 ]; }; testIfilter0Last = { expr = ifilter0 (i: v: i == 5) [ 10 11 12 13 14 15 ]; expected = [ 15 ]; }; testFold = let f = op: fold: fold op 0 (range 0 100); Loading