Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

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.
base fork: erlang/otp
base: master
...
head fork: seancribbs/otp
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
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.