lib.lists.findFirstIndex: init
Co-authored-by: Robert Hensing <roberth@users.noreply.github.com>
This commit is contained in:
@@ -180,18 +180,18 @@ rec {
|
|||||||
else if len != 1 then multiple
|
else if len != 1 then multiple
|
||||||
else head found;
|
else head found;
|
||||||
|
|
||||||
/* Find the first element in the list matching the specified
|
/* Find the first index in the list matching the specified
|
||||||
predicate or return `default` if no such element exists.
|
predicate or return `default` if no such element exists.
|
||||||
|
|
||||||
Type: findFirst :: (a -> bool) -> a -> [a] -> a
|
Type: findFirstIndex :: (a -> Bool) -> b -> [a] -> (Int | b)
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
findFirst (x: x > 3) 7 [ 1 6 4 ]
|
findFirstIndex (x: x > 3) null [ 0 6 4 ]
|
||||||
=> 6
|
=> 1
|
||||||
findFirst (x: x > 9) 7 [ 1 6 4 ]
|
findFirstIndex (x: x > 9) null [ 0 6 4 ]
|
||||||
=> 7
|
=> null
|
||||||
*/
|
*/
|
||||||
findFirst =
|
findFirstIndex =
|
||||||
# Predicate
|
# Predicate
|
||||||
pred:
|
pred:
|
||||||
# Default value to return
|
# Default value to return
|
||||||
@@ -229,7 +229,33 @@ rec {
|
|||||||
if resultIndex < 0 then
|
if resultIndex < 0 then
|
||||||
default
|
default
|
||||||
else
|
else
|
||||||
elemAt list resultIndex;
|
resultIndex;
|
||||||
|
|
||||||
|
/* Find the first element in the list matching the specified
|
||||||
|
predicate or return `default` if no such element exists.
|
||||||
|
|
||||||
|
Type: findFirst :: (a -> bool) -> a -> [a] -> a
|
||||||
|
|
||||||
|
Example:
|
||||||
|
findFirst (x: x > 3) 7 [ 1 6 4 ]
|
||||||
|
=> 6
|
||||||
|
findFirst (x: x > 9) 7 [ 1 6 4 ]
|
||||||
|
=> 7
|
||||||
|
*/
|
||||||
|
findFirst =
|
||||||
|
# Predicate
|
||||||
|
pred:
|
||||||
|
# Default value to return
|
||||||
|
default:
|
||||||
|
# Input list
|
||||||
|
list:
|
||||||
|
let
|
||||||
|
index = findFirstIndex pred null list;
|
||||||
|
in
|
||||||
|
if index == null then
|
||||||
|
default
|
||||||
|
else
|
||||||
|
elemAt list index;
|
||||||
|
|
||||||
/* Return true if function `pred` returns true for at least one
|
/* Return true if function `pred` returns true for at least one
|
||||||
element of `list`.
|
element of `list`.
|
||||||
|
|||||||
@@ -518,45 +518,55 @@ runTests {
|
|||||||
expected = false;
|
expected = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
testFindFirstExample1 = {
|
testFindFirstIndexExample1 = {
|
||||||
expr = findFirst (x: x > 3) 7 [ 1 6 4 ];
|
expr = lists.findFirstIndex (x: x > 3) (abort "index found, so a default must not be evaluated") [ 1 6 4 ];
|
||||||
expected = 6;
|
expected = 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
testFindFirstExample2 = {
|
testFindFirstIndexExample2 = {
|
||||||
expr = findFirst (x: x > 9) 7 [ 1 6 4 ];
|
expr = lists.findFirstIndex (x: x > 9) "a very specific default" [ 1 6 4 ];
|
||||||
expected = 7;
|
expected = "a very specific default";
|
||||||
};
|
};
|
||||||
|
|
||||||
testFindFirstEmpty = {
|
testFindFirstIndexEmpty = {
|
||||||
expr = findFirst (abort "when the list is empty, the predicate is not needed") null [];
|
expr = lists.findFirstIndex (abort "when the list is empty, the predicate is not needed") null [];
|
||||||
expected = null;
|
expected = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
testFindFirstSingleMatch = {
|
testFindFirstIndexSingleMatch = {
|
||||||
expr = findFirst (x: x == 5) null [ 5 ];
|
expr = lists.findFirstIndex (x: x == 5) null [ 5 ];
|
||||||
expected = 5;
|
expected = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
testFindFirstSingleDefault = {
|
testFindFirstIndexSingleDefault = {
|
||||||
expr = findFirst (x: false) null [ (abort "if the predicate doesn't access the value, it must not be evaluated") ];
|
expr = lists.findFirstIndex (x: false) null [ (abort "if the predicate doesn't access the value, it must not be evaluated") ];
|
||||||
expected = null;
|
expected = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
testFindFirstNone = {
|
testFindFirstIndexNone = {
|
||||||
expr = builtins.tryEval (findFirst (x: x == 2) null [ 1 (throw "the last element must be evaluated when there's no match") ]);
|
expr = builtins.tryEval (lists.findFirstIndex (x: x == 2) null [ 1 (throw "the last element must be evaluated when there's no match") ]);
|
||||||
expected = { success = false; value = false; };
|
expected = { success = false; value = false; };
|
||||||
};
|
};
|
||||||
|
|
||||||
# Makes sure that the implementation doesn't cause a stack overflow
|
# Makes sure that the implementation doesn't cause a stack overflow
|
||||||
testFindFirstBig = {
|
testFindFirstIndexBig = {
|
||||||
expr = findFirst (x: x == 1000000) null (range 0 1000000);
|
expr = lists.findFirstIndex (x: x == 1000000) null (range 0 1000000);
|
||||||
expected = 1000000;
|
expected = 1000000;
|
||||||
};
|
};
|
||||||
|
|
||||||
testFindFirstLazy = {
|
testFindFirstIndexLazy = {
|
||||||
expr = findFirst (x: x == 1) 7 [ 1 (abort "list elements after the match must not be evaluated") ];
|
expr = lists.findFirstIndex (x: x == 1) null [ 1 (abort "list elements after the match must not be evaluated") ];
|
||||||
expected = 1;
|
expected = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
testFindFirstExample1 = {
|
||||||
|
expr = lists.findFirst (x: x > 3) 7 [ 1 6 4 ];
|
||||||
|
expected = 6;
|
||||||
|
};
|
||||||
|
|
||||||
|
testFindFirstExample2 = {
|
||||||
|
expr = lists.findFirst (x: x > 9) 7 [ 1 6 4 ];
|
||||||
|
expected = 7;
|
||||||
};
|
};
|
||||||
|
|
||||||
# ATTRSETS
|
# ATTRSETS
|
||||||
|
|||||||
Reference in New Issue
Block a user