Merge pull request #214021 from tweag/ifilter0
lib.lists.ifilter0: init
This commit is contained in:
commit
24af4c04ee
3 changed files with 77 additions and 2 deletions
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
@ -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.
|
||||
|
||||
|
|
|
@ -63,8 +63,10 @@ let
|
|||
hasAttrByPath
|
||||
hasInfix
|
||||
id
|
||||
ifilter0
|
||||
isStorePath
|
||||
lazyDerivation
|
||||
length
|
||||
lists
|
||||
listToAttrs
|
||||
makeExtensible
|
||||
|
@ -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…
Reference in a new issue