From 3ac04f901ecfb3fed128759964ccc54fa4ee7b2a Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Tue, 30 Apr 2013 10:10:03 +0200 Subject: Rename and document lists:zf/2 as lists:filtermap/2 This function is used all over the place in OTP itself and people sometimes want that functionality, they may as well not reimplement it themselves. --- lib/et/doc/src/et_desc.xmlsrc | 2 +- lib/stdlib/doc/src/lists.xml | 25 +++++++++++++++++++++++++ lib/stdlib/src/lists.erl | 24 +++++++++++++++++------- lib/stdlib/test/lists_SUITE.erl | 4 ++-- 4 files changed, 45 insertions(+), 10 deletions(-) (limited to 'lib') diff --git a/lib/et/doc/src/et_desc.xmlsrc b/lib/et/doc/src/et_desc.xmlsrc index c02517ae01..36274f6316 100644 --- a/lib/et/doc/src/et_desc.xmlsrc +++ b/lib/et/doc/src/et_desc.xmlsrc @@ -150,7 +150,7 @@ NewEvent = #event{}]]>

The interface of the filter function is the same as the the - filter functions for the good old lists:zf/2. If the filter + filter functions for the good old lists:filtermap/2. If the filter returns false it means that the trace data should silently be dropped. true means that the trace data data already is an Event Record and that it should be kept as it is. diff --git a/lib/stdlib/doc/src/lists.xml b/lib/stdlib/doc/src/lists.xml index b6c0fa4e05..1aff78f4fc 100644 --- a/lib/stdlib/doc/src/lists.xml +++ b/lib/stdlib/doc/src/lists.xml @@ -151,6 +151,31 @@ true.

+ + + Filter and map elements which satisfy a function + +

Calls Fun(Elem) on successive elements Elem + of List1. Fun/2 must return either a boolean + or a tuple {true, Value}. The function returns the list of elements + for which Fun returns a new value, where a value of true + is synonymous with {true, Elem}.

+

That is, filtermap behaves as if it had been defined as follows:

+ +filtermap(Fun, List1) -> + lists:foldr(fun(Elem, Acc) -> + case Fun(Elem) of + false -> Acc; + true -> [Elem|Acc]; + {true,Value} -> [Value|Acc] + end, + end, [], List1). +

Example:

+
+> lists:filtermap(fun(X) -> case X rem 2 of 0 -> {true, X div 2}; _ -> false end end, [1,2,3,4,5]).
+[1,2]
+
+
Length of flattened deep list diff --git a/lib/stdlib/src/lists.erl b/lib/stdlib/src/lists.erl index 961c060019..0c033acd88 100644 --- a/lib/stdlib/src/lists.erl +++ b/lib/stdlib/src/lists.erl @@ -36,7 +36,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, - partition/2,zf/2, + partition/2,zf/2,filtermap/2, mapfoldl/3,mapfoldr/3,foreach/2,takewhile/2,dropwhile/2,splitwith/2, split/2]). @@ -1291,18 +1291,28 @@ partition(Pred, [H | T], As, Bs) -> partition(Pred, [], As, Bs) when is_function(Pred, 1) -> {reverse(As), reverse(Bs)}. --spec zf(fun((T) -> boolean() | {'true', X}), [T]) -> [(T | X)]. +-spec filtermap(Fun, List1) -> List2 when + Fun :: fun((Elem) -> boolean() | {'true', Value}), + List1 :: [Elem], + List2 :: [Elem | Value], + Elem :: term(), + Value :: term(). -zf(F, [Hd|Tail]) -> +filtermap(F, [Hd|Tail]) -> case F(Hd) of true -> - [Hd|zf(F, Tail)]; + [Hd|filtermap(F, Tail)]; {true,Val} -> - [Val|zf(F, Tail)]; + [Val|filtermap(F, Tail)]; false -> - zf(F, Tail) + filtermap(F, Tail) end; -zf(F, []) when is_function(F, 1) -> []. +filtermap(F, []) when is_function(F, 1) -> []. + +-spec zf(fun((T) -> boolean() | {'true', X}), [T]) -> [(T | X)]. + +zf(F, L) -> + filtermap(F, L). -spec foreach(Fun, List) -> ok when Fun :: fun((Elem :: T) -> term()), diff --git a/lib/stdlib/test/lists_SUITE.erl b/lib/stdlib/test/lists_SUITE.erl index b56f0b39d8..cd7210f8ec 100644 --- a/lib/stdlib/test/lists_SUITE.erl +++ b/lib/stdlib/test/lists_SUITE.erl @@ -2532,8 +2532,8 @@ otp_5939(Config) when is_list(Config) -> ?line [] = lists:filter(Pred, []), ?line {'EXIT', _} = (catch lists:partition(func, [])), ?line {[],[]} = lists:partition(Pred, []), - ?line {'EXIT', _} = (catch lists:zf(func, [])), - ?line [] = lists:zf(Fun1, []), + ?line {'EXIT', _} = (catch lists:filtermap(func, [])), + ?line [] = lists:filtermap(Fun1, []), ?line {'EXIT', _} = (catch lists:foreach(func, [])), ?line ok = lists:foreach(Fun1, []), ?line {'EXIT', _} = (catch lists:mapfoldl(func, [], [])), -- cgit v1.2.3