Skip to content

Commit

Permalink
Implement lists:keytake/3
Browse files Browse the repository at this point in the history
  • Loading branch information
petermm committed Jun 11, 2024
1 parent b4a413c commit 14ceb31
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Simple http client, that can be used for different use case such as downloading OTA updates
- Elixir support for `Keyword.merge` `Keyword.take` `Keyword.pop(!)` `Keyword.keyword?` `Keyword.has_key?` functions.
- lists:keytake/3 implemented.

### Changed

Expand Down
26 changes: 26 additions & 0 deletions libs/estdlib/src/lists.erl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
%
% Copyright 2017-2023 Fred Dushin <[email protected]>
% split/2 function Copyright Ericsson AB 1996-2023.
% keytake/3 function Copyright Ericsson AB 1996-2024.
%
% Licensed under the Apache License, Version 2.0 (the "License");
% you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -40,6 +41,7 @@
keyfind/3,
keymember/3,
keyreplace/4,
keytake/3,
foldl/3,
foldr/3,
all/2,
Expand Down Expand Up @@ -304,6 +306,30 @@ keyreplace(K, I, [H | T], L, NewTuple, NewList) when is_tuple(H) andalso is_tupl
keyreplace(K, I, [H | T], L, NewTuple, NewList) ->
keyreplace(K, I, T, L, NewTuple, [H | NewList]).

%%-----------------------------------------------------------------------------
%% @param Key the key to match
%% @param N the position in the tuple to compare (1..tuple_size)
%% @param TupleList1 the list of tuples from which to find the element
%% @returns `{value, Tuple, TupleList2}` if such a tuple is found, otherwise `false`. `TupleList2` is a copy of `TupleList1` where the first occurrence of `Tuple` has been removed.
%% @doc Searches the list of tuples `TupleList1` for a tuple whose `N`th element
%% compares equal to `Key`.
%% @end
%%-----------------------------------------------------------------------------
-spec keytake(Key, N, TupleList1) -> {value, Tuple, TupleList2} | false when
Key :: term(),
N :: pos_integer(),
TupleList1 :: [tuple()],
TupleList2 :: [tuple()],
Tuple :: tuple().
keytake(Key, N, L) when is_integer(N), N > 0 ->
keytake(Key, N, L, []).
keytake(Key, N, [H | T], L) when element(N, H) == Key ->
{value, H, lists:reverse(L, T)};
keytake(Key, N, [H | T], L) ->
keytake(Key, N, T, [H | L]);
keytake(_K, _N, [], _L) ->
false.

%%-----------------------------------------------------------------------------
%% @param Fun the function to apply
%% @param Acc0 the initial accumulator
Expand Down
14 changes: 14 additions & 0 deletions tests/libs/estdlib/test_lists.erl
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ test() ->
ok = test_keyfind(),
ok = test_keydelete(),
ok = test_keyreplace(),
ok = test_keytake(),
ok = test_foldl(),
ok = test_foldr(),
ok = test_all(),
Expand Down Expand Up @@ -105,6 +106,19 @@ test_keyreplace() ->
]),
ok.

test_keytake() ->
List1 = [{name, "Joe"}, {name, "Robert"}, {name, "Mike"}],
?ASSERT_MATCH(
lists:keytake("Joe", 2, List1), {value, {name, "Joe"}, [{name, "Robert"}, {name, "Mike"}]}
),
?ASSERT_MATCH(
lists:keytake("Robert", 2, List1),
{value, {name, "Robert"}, [{name, "Joe"}, {name, "Mike"}]}
),
?ASSERT_MATCH(lists:keytake("Joe", 1, List1), false),
?ASSERT_MATCH(lists:keytake("Joe", 3, List1), false),
ok.

test_foldl() ->
?ASSERT_MATCH(lists:foldl(fun(I, Accum) -> Accum + I end, 0, [1, 2, 3, 4, 5]), 15),
?ASSERT_MATCH(lists:foldl(fun(I, Accum) -> Accum + I end, 0, []), 0),
Expand Down

0 comments on commit 14ceb31

Please sign in to comment.