lib.lists.ifilter0: init

This commit is contained in:
Silvan Mosberger 2023-02-01 18:27:23 +01:00
parent f98e5d632f
commit 6861ef7707
3 changed files with 77 additions and 2 deletions

View file

@ -89,7 +89,7 @@ let
recurseIntoAttrs dontRecurseIntoAttrs cartesianProduct cartesianProductOfSets recurseIntoAttrs dontRecurseIntoAttrs cartesianProduct cartesianProductOfSets
mapCartesianProduct updateManyAttrsByPath; mapCartesianProduct updateManyAttrsByPath;
inherit (self.lists) singleton forEach foldr fold foldl foldl' imap0 imap1 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 optional optionals toList range replicate partition zipListsWith zipLists
reverseList listDfs toposort sort sortOn naturalSort compareLists take reverseList listDfs toposort sort sortOn naturalSort compareLists take
drop sublist last init crossLists unique allUnique intersectLists drop sublist last init crossLists unique allUnique intersectLists

View file

@ -4,7 +4,7 @@
{ lib }: { lib }:
let let
inherit (lib.strings) toInt; inherit (lib.strings) toInt;
inherit (lib.trivial) compare min id warn; inherit (lib.trivial) compare min id warn pipe;
inherit (lib.attrsets) mapAttrs; inherit (lib.attrsets) mapAttrs;
in in
rec { rec {
@ -333,6 +333,54 @@ rec {
*/ */
imap1 = f: list: genList (n: f (n + 1) (elemAt list n)) (length list); 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. Map and concatenate the result.

View file

@ -63,8 +63,10 @@ let
hasAttrByPath hasAttrByPath
hasInfix hasInfix
id id
ifilter0
isStorePath isStorePath
lazyDerivation lazyDerivation
length
lists lists
listToAttrs listToAttrs
makeExtensible makeExtensible
@ -651,6 +653,31 @@ runTests {
expected = ["b" "c"]; 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 = testFold =
let let
f = op: fold: fold op 0 (range 0 100); f = op: fold: fold op 0 (range 0 100);