Skip to content

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
...
Checking mergeability… Don’t worry, you can still create the pull request.
  • 1 commit
  • 3 files changed
  • 0 commit comments
  • 1 contributor
Commits on Nov 14, 2013
@seancribbs seancribbs Add lists:find/2,3
lists:find/2,3 returns the first element of the passed list for which
the predicate fun returns true. If no elements result in the predicate
being true, 'false' (/2) or the given default value (/3) is returned.
5426dae
Showing with 68 additions and 2 deletions.
  1. +22 −0 lib/stdlib/doc/src/lists.xml
  2. +26 −1 lib/stdlib/src/lists.erl
  3. +20 −1 lib/stdlib/test/lists_SUITE.erl
View
22 lib/stdlib/doc/src/lists.xml
@@ -177,6 +177,28 @@ filtermap(Fun, List1) ->
</desc>
</func>
<func>
+ <name name="find" arity="2" />
+ <fsummary>Find the first element which satisfies a predicate</fsummary>
+ <desc>
+ <p>Returns <c>{value, <anno>Elem</anno>}</c> for the first
+ element <c><anno>Elem</anno></c> of <c><anno>List</anno></c>
+ for which <c><anno>Pred</anno>(<anno>Elem</anno>)</c>
+ returns <c>true</c>, or <c>false</c>.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name name="find" arity="3" />
+ <fsummary>Find the first element which satisfies a predicate</fsummary>
+ <desc>
+ <p>Returns <c>{value, <anno>Elem</anno>}</c> for the first
+ element <c><anno>Elem</anno></c> of <c><anno>List</anno></c>
+ for which <c><anno>Pred</anno>(<anno>Elem</anno>)</c> returns
+ <c>true</c>, or <c><anno>Default</anno></c>.
+ </p>
+ </desc>
+ </func>
+ <func>
<name name="flatlength" arity="1"/>
<fsummary>Length of flattened deep list</fsummary>
<desc>
View
27 lib/stdlib/src/lists.erl
@@ -35,7 +35,7 @@
-export([merge/3, rmerge/3, sort/2, umerge/3, rumerge/3, usort/2]).
--export([all/2,any/2,map/2,flatmap/2,foldl/3,foldr/3,filter/2,
+-export([all/2,any/2,map/2,find/2,find/3,flatmap/2,foldl/3,foldr/3,filter/2,
partition/2,zf/2,filtermap/2,
mapfoldl/3,mapfoldr/3,foreach/2,takewhile/2,dropwhile/2,splitwith/2,
split/2]).
@@ -1270,6 +1270,31 @@ foldr(F, Accu, []) when is_function(F, 2) -> Accu.
filter(Pred, List) when is_function(Pred, 1) ->
[ E || E <- List, Pred(E) ].
+%% Equivalent to find(Pred, List, false).
+
+-spec find(Pred, List) -> {value, Elem} | false when
+ Pred :: fun((Elem :: T) -> boolean()),
+ List :: [T],
+ Elem :: T,
+ T :: term().
+
+find(Pred, List) when is_function(Pred, 1) ->
+ find(Pred, List, false).
+
+-spec find(Pred, List, Default) -> {value, Elem} | Default when
+ Pred :: fun((Elem :: T) -> boolean()),
+ List :: [T],
+ Elem :: T,
+ T :: term(),
+ Default :: term().
+
+find(Pred, [], Default) when is_function(Pred, 1) -> Default;
+find(Pred, [H|T], Default) ->
+ case Pred(H) of
+ true -> {value, H};
+ false -> find(Pred, T, Default)
+ end.
+
%% Equivalent to {filter(F, L), filter(NotF, L)}, if NotF = 'fun(X) ->
%% not F(X) end'.
View
21 lib/stdlib/test/lists_SUITE.erl
@@ -60,6 +60,7 @@
ufunsort_error/1,
zip_unzip/1, zip_unzip3/1, zipwith/1, zipwith3/1,
filter_partition/1,
+ find/1,
otp_5939/1, otp_6023/1, otp_6606/1, otp_7230/1,
suffix/1, subtract/1]).
@@ -85,7 +86,7 @@ all() ->
{group, usort}, {group, keysort}, {group, ukeysort},
{group, funsort}, {group, ufunsort}, {group, sublist},
{group, flatten}, {group, seq}, zip_unzip, zip_unzip3,
- zipwith, zipwith3, filter_partition, {group, tickets},
+ zipwith, zipwith3, filter_partition, find, {group, tickets},
suffix, subtract].
groups() ->
@@ -2480,6 +2481,24 @@ filpart(F, All, Exp) ->
Other = lists:filter(fun(E) -> not F(E) end, All),
{Exp,Other} = lists:partition(F, All).
+%% Test lists:find/2,3
+find(Config) when is_list(Config) ->
+ F = fun(I) -> I rem 2 =:= 0 end,
+ F2 = fun(A,B) -> A > B end,
+
+ ?line {value, 2} = lists:find(F, [1,2,3,4]),
+ ?line false = lists:find(F, [1,3,5,7]),
+ ?line false = lists:find(F, []),
+ ?line {value, 2} = lists:find(F, [1,2,3,4], notfound),
+ ?line notfound = lists:find(F, [1,3,5,7], notfound),
+ ?line notfound = lists:find(F, [], notfound),
+
+ %% Error cases.
+ ?line {'EXIT',{function_clause,_}} = (catch lists:find(badfun, [])),
+ ?line {'EXIT',{function_clause,_}} = (catch lists:find(badfun, [], notfound)),
+ ?line {'EXIT',{function_clause,_}} = (catch lists:find(F2, [])),
+ ?line {'EXIT',{function_clause,_}} = (catch lists:find(F2, [], notfound)),
+ ok.
otp_5939(doc) -> ["OTP-5939. Guard tests added."];
otp_5939(suite) -> [];

No commit comments for this range

Something went wrong with that request. Please try again.