From 61d0d7555376ea261f1ddfc06d7d3a4dc2fdfc70 Mon Sep 17 00:00:00 2001 From: Paul Guyot Date: Sun, 13 Jul 2025 17:49:02 +0200 Subject: [PATCH] Add `lists:keysort/2` Signed-off-by: Paul Guyot --- CHANGELOG.md | 4 ++++ libs/estdlib/src/lists.erl | 12 ++++++++++++ tests/libs/estdlib/test_lists.erl | 13 +++++++++++++ 3 files changed, 29 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a9759e699..e128d458b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.6.7] - Unreleased +### Added + +- Added `lists:keysort/2` + ### Fixed - Fixed a bug where binary matching could fail due to a missing preservation of the matched binary. diff --git a/libs/estdlib/src/lists.erl b/libs/estdlib/src/lists.erl index 9aecce8342..2fc12a3e93 100644 --- a/libs/estdlib/src/lists.erl +++ b/libs/estdlib/src/lists.erl @@ -43,6 +43,7 @@ keyfind/3, keymember/3, keyreplace/4, + keysort/2, keystore/4, keytake/3, foldl/3, @@ -330,6 +331,17 @@ keyreplace(Key, N, [H | Tail], _OrigL, NewTuple, Acc) when element(N, H) =:= Key keyreplace(Key, N, [H | Tail], OrigL, NewTuple, Acc) -> keyreplace(Key, N, Tail, OrigL, NewTuple, [H | Acc]). +%%----------------------------------------------------------------------------- +%% @param N the position in the tuple to compare (1..tuple_size) +%% @param L the list to sort +%% @returns The list L sorted by Nth element +%% @doc Sort a list of tuples by Nth element. +%% @end +%%----------------------------------------------------------------------------- +-spec keysort(N :: pos_integer(), L :: [tuple()]) -> [tuple()]. +keysort(N, TupleList) -> + sort(fun(E1, E2) -> element(N, E1) < element(N, E2) end, TupleList). + %%----------------------------------------------------------------------------- %% @param Key the key to match %% @param N the position in the tuple to compare (1..tuple_size) diff --git a/tests/libs/estdlib/test_lists.erl b/tests/libs/estdlib/test_lists.erl index 72dc3bf494..b45c4f47f5 100644 --- a/tests/libs/estdlib/test_lists.erl +++ b/tests/libs/estdlib/test_lists.erl @@ -32,6 +32,7 @@ test() -> ok = test_keyfind(), ok = test_keydelete(), ok = test_keyreplace(), + ok = test_keysort(), ok = test_keystore(), ok = test_keytake(), ok = test_foldl(), @@ -120,6 +121,18 @@ test_keyreplace() -> ]), ok. +test_keysort() -> + ?ASSERT_MATCH(lists:keysort(1, [{2, foo}, {1, bar}]), [{1, bar}, {2, foo}]), + ?ASSERT_MATCH(lists:keysort(1, [{2, foobar}, {1, foo}, {1, bar}]), [ + {1, foo}, {1, bar}, {2, foobar} + ]), + ?ASSERT_MATCH(lists:keysort(1, [{2, foo, zot}, {1, bar}]), [{1, bar}, {2, foo, zot}]), + ?ASSERT_MATCH(lists:keysort(1, []), []), + ?ASSERT_MATCH(lists:keysort(2, [{foo, 2}, {bar, 1}]), [{bar, 1}, {foo, 2}]), + ?ASSERT_ERROR(lists:keysort(1, [1, 2])), + ?ASSERT_ERROR(lists:keysort(3, [{1, bar}, {2, foo}])), + ok. + test_keystore() -> ?ASSERT_MATCH(lists:keystore(a, 1, [], {foo, bar}), [{foo, bar}]), ?ASSERT_MATCH(lists:keystore(a, 1, [{a, x}, b, []], {1, 2}), [{1, 2}, b, []]),