Skip to content

Commit

Permalink
Add count/2 function to riak_core_util
Browse files Browse the repository at this point in the history
This is useful for determining how many elements of a list match a
certain criteria, without having to waste memory on intermediate lists,
and without having to rewrite the fold yourself every time. Similar to
Enum.count from Elixir.
  • Loading branch information
nickelization committed Dec 13, 2016
1 parent f589d27 commit 84162df
Showing 1 changed file with 21 additions and 0 deletions.
21 changes: 21 additions & 0 deletions src/riak_core_util.erl
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
safe_rpc/5,
rpc_every_member/4,
rpc_every_member_ann/4,
count/2,
keydelete/2,
multi_keydelete/2,
multi_keydelete/3,
Expand Down Expand Up @@ -79,6 +80,7 @@
-include("riak_core_vnode.hrl").

-ifdef(TEST).
-include_lib("eqc/include/eqc.hrl").
-include_lib("eunit/include/eunit.hrl").
-export([counter_loop/1,incr_counter/1,decr_counter/1]).
-endif.
Expand Down Expand Up @@ -318,6 +320,18 @@ ensure_started(App) ->
ok
end.

%% @doc Applies `Pred' to each element in `List', and returns a count of how many
%% applications returned `true'.
-spec count(fun((term()) -> boolean()), [term()]) -> non_neg_integer().
count(Pred, List) ->
FoldFun = fun(E, A) ->
case Pred(E) of
false -> A;
true -> A + 1
end
end,
lists:foldl(FoldFun, 0, List).

%% @doc Returns a copy of `TupleList' where the first occurrence of a tuple whose
%% first element compares equal to `Key' is deleted, if there is such a tuple.
%% Equivalent to `lists:keydelete(Key, 1, TupleList)'.
Expand Down Expand Up @@ -930,6 +944,13 @@ incr_counter(CounterPid) ->
decr_counter(CounterPid) ->
CounterPid ! down.

count_test() ->
?assert(eqc:quickcheck(prop_count_correct())).

prop_count_correct() ->
?FORALL(List, list(bool()),
count(fun(E) -> E end, List) =:= length([E || E <- List, E])).

multi_keydelete_test_() ->
Languages = [{lisp, 1958},
{ml, 1973},
Expand Down

0 comments on commit 84162df

Please sign in to comment.