Skip to content

Commit

Permalink
Merge pull request #1019 from petermm/lists-split/2
Browse files Browse the repository at this point in the history
Implement lists:split/2

As implemented in lists: module in OTP
https://github.com/erlang/otp/blob/0e66b88db447954e1de70ec1fa0822d3a7e6133d/lib/stdlib/src/lists.erl#L1808

These changes are made under both the "Apache 2.0" and the "GNU Lesser General
Public License 2.1 or later" license terms (dual license).

SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
  • Loading branch information
bettio committed Jan 31, 2024
2 parents 665dc89 + 30d5af4 commit f26a643
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added support for `pico` and `poci` as an alternative to `mosi` and `miso` for SPI
- ESP32: Added support to SPI peripherals other than hspi and vspi
- Added `gpio:set_int/4`, with the 4th parameter being the pid() or registered name of the process to receive interrupt messages
- Added support for `lists:split/2`

### Changed

Expand Down
35 changes: 35 additions & 0 deletions libs/estdlib/src/lists.erl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
% This file is part of AtomVM.
%
% Copyright 2017-2023 Fred Dushin <fred@dushin.net>
% split/2 function Copyright Ericsson AB 1996-2023.
%
% 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 @@ -49,6 +50,7 @@
join/2,
seq/2, seq/3,
sort/1, sort/2,
split/2,
usort/1, usort/2,
duplicate/2,
sublist/2
Expand Down Expand Up @@ -502,6 +504,39 @@ sort(List) when is_list(List) ->
sort(Fun, List) when is_function(Fun), is_list(List) ->
quick_sort(Fun, List).

%%-----------------------------------------------------------------------------
%% @param N elements non negative Integer
%% @param List1 list to split
%% @returns Tuple with the two lists
%% @doc Splits List1 into List2 and List3. List2 contains the first N elements
%% and List3 the remaining elements (the Nth tail).
%% @end
%%-----------------------------------------------------------------------------
%% Attribution: https://github.com/erlang/otp/blob/5c8a9cbd125f3db5f5d13ff5ba2a12c076912425/lib/stdlib/src/lists.erl#L1801
-spec split(N, List1) -> {List2, List3} when
N :: non_neg_integer(),
List1 :: [T],
List2 :: [T],
List3 :: [T],
T :: term().

split(N, List) when is_integer(N), N >= 0, is_list(List) ->
case split(N, List, []) of
{_, _} = Result ->
Result;
Fault when is_atom(Fault) ->
erlang:error(Fault, [N, List])
end;
split(N, List) ->
erlang:error(badarg, [N, List]).

split(0, L, R) ->
{lists:reverse(R, []), L};
split(N, [H | T], R) ->
split(N - 1, T, [H | R]);
split(_, [], _) ->
badarg.

%% Attribution: https://erlang.org/doc/programming_examples/list_comprehensions.html#quick-sort
%% @private
quick_sort(Fun, [Pivot | T]) ->
Expand Down
18 changes: 18 additions & 0 deletions tests/libs/estdlib/test_lists.erl
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ test() ->
ok = test_join(),
ok = test_seq(),
ok = test_sort(),
ok = test_split(),
ok = test_usort(),
ok.

Expand Down Expand Up @@ -210,6 +211,23 @@ test_sort() ->

ok.

test_split() ->
?ASSERT_MATCH(
lists:split(1, ["Foo", "Bar", "Alice", "Bob", "lowercase"]),
{["Foo"], ["Bar", "Alice", "Bob", "lowercase"]}
),
?ASSERT_MATCH(
lists:split(4, ["Foo", "Bar", "Alice", "Bob", "lowercase"]),
{["Foo", "Bar", "Alice", "Bob"], ["lowercase"]}
),
?ASSERT_MATCH(lists:split(0, []), {[], []}),
?ASSERT_MATCH(lists:split(0, ["Foo"]), {[], ["Foo"]}),
?ASSERT_MATCH(lists:split(1, ["Foo"]), {["Foo"], []}),
?ASSERT_ERROR(lists:split(1, []), badarg),
?ASSERT_ERROR(lists:split(2, ["Foo"]), badarg),
?ASSERT_ERROR(lists:split(-1, ["Foo"]), badarg),
ok.

test_usort() ->
?ASSERT_MATCH(lists:usort([]), []),
?ASSERT_MATCH(lists:usort([1]), [1]),
Expand Down

0 comments on commit f26a643

Please sign in to comment.