Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:24
erlang
5531-Adding-lists-uniq-1-and-lists-uniq-2.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 5531-Adding-lists-uniq-1-and-lists-uniq-2.patch of Package erlang
From de65b7f94dd846fbebc3d64272495da623197bab Mon Sep 17 00:00:00 2001 From: Gian Lorenzo Meocci <glmeocci@gmail.com> Date: Thu, 3 Mar 2022 10:31:05 +0100 Subject: [PATCH] Adding lists:uniq/1 and lists:uniq/2 --- lib/stdlib/doc/src/lists.xml | 37 +++++++++++++++++++++++++++ lib/stdlib/src/lists.erl | 45 +++++++++++++++++++++++++++++++-- lib/stdlib/test/lists_SUITE.erl | 28 +++++++++++++++++--- 3 files changed, 105 insertions(+), 5 deletions(-) diff --git a/lib/stdlib/doc/src/lists.xml b/lib/stdlib/doc/src/lists.xml index 063c9d19a8..8b39279b48 100644 --- a/lib/stdlib/doc/src/lists.xml +++ b/lib/stdlib/doc/src/lists.xml @@ -1126,6 +1126,43 @@ splitwith(Pred, List) -> [[a,x,1],[b,y,2],[c,z,3]]</pre> </desc> </func> + + <func> + <name name="uniq" arity="1" since="OTP 25.0"/> + <fsummary>Removes duplicate elements of a list preserving the order.</fsummary> + <desc> + <p>Returns a list containing the elements of + <c><anno>List1</anno></c> with duplicated elements removed + (preserving the order of the elements). The first occurrence of + each element is kept.</p> + <p><em>Examples:</em></p> + <pre> +> <input>lists:uniq(fun([3,3,1,2,1,2,3]).</input> +[3,1,2] +> <input>lists:uniq([a, a, 1, b, 2, a, 3]).</input> +[a, 1, b, 2, 3]</pre> + </desc> + </func> + + <func> + <name name="uniq" arity="2" since="OTP 25.0"/> + <fsummary> + Removes duplicate elements of a list using + a fun as a key preserving the order. + </fsummary> + <desc> + <p>Returns a list containing the elements of + <c><anno>List1</anno></c> without the elements for which + <c><anno>Fun</anno></c> returned duplicate values + (preserving the order of the elements). The first occurrence + of each element is kept.</p> + <p><em>Examples:</em></p> + <pre> +> <input>lists:uniq(fun({X, _}) -> X end, [{b, 2}, {a, 1}, {c, 3}, {a, 2}]).</input> +[{b, 2}, {a, 1}, {c, 3}]</pre> + </desc> + </func> + </funcs> </erlref> diff --git a/lib/stdlib/src/lists.erl b/lib/stdlib/src/lists.erl index 2a9122384b..96898a88f5 100644 --- a/lib/stdlib/src/lists.erl +++ b/lib/stdlib/src/lists.erl @@ -36,7 +36,7 @@ prefix/2, reverse/1, seq/2, seq/3, split/2, sublist/2, sublist/3, subtract/2, suffix/2, sum/1, - unzip/1, unzip3/1, + uniq/1, unzip/1, unzip3/1, zip/2, zip3/3]). %% Functions taking a list of tuples and a position within the tuple. @@ -59,7 +59,7 @@ foldl/3, foldr/3, foreach/2, map/2, mapfoldl/3, mapfoldr/3, partition/2, search/2, - splitwith/2, takewhile/2, + splitwith/2, takewhile/2, uniq/2, zipwith/3, zipwith3/4]). %% Undocumented, but used within Erlang/OTP. @@ -2975,3 +2975,44 @@ rufmerge2_2(H1, T1, Fun, [], M, H2M) -> lists:reverse(T1, [H1, H2M | M]) end. +%% uniq/1: return a new list with the unique elements of the given list + +-spec uniq(List1) -> List2 when + List1 :: [T], + List2 :: [T], + T :: term(). + +uniq(L) -> + uniq_1(L, #{}). + +uniq_1([X | Xs], M) -> + case is_map_key(X, M) of + true -> + uniq_1(Xs, M); + false -> + [X | uniq_1(Xs, M#{X => true})] + end; +uniq_1([], _) -> + []. + +%% uniq/2: return a new list with the unique elements of the given list using a function key + +-spec uniq(Fun, List1) -> List2 when + Fun :: fun((T) -> any()), + List1 :: [T], + List2 :: [T], + T :: term(). + +uniq(F, L) when is_function(F, 1) -> + uniq_2(L, F, #{}). + +uniq_2([X | Xs], F, M) -> + Key = F(X), + case is_map_key(Key, M) of + true -> + uniq_2(Xs, F, M); + false -> + [X | uniq_2(Xs, F, M#{Key => true})] + end; +uniq_2([], _, _) -> + []. diff --git a/lib/stdlib/test/lists_SUITE.erl b/lib/stdlib/test/lists_SUITE.erl index 68fb1cd92f..26b71887fa 100644 --- a/lib/stdlib/test/lists_SUITE.erl +++ b/lib/stdlib/test/lists_SUITE.erl @@ -32,7 +32,7 @@ %% Test cases must be exported. -export([member/1, reverse/1, keymember/1, keysearch_keyfind/1, - keystore/1, keytake/1, keyreplace/1, + keystore/1, keytake/1, keyreplace/1, append_1/1, append_2/1, seq_loop/1, seq_2/1, seq_3/1, seq_2_e/1, seq_3_e/1, @@ -53,12 +53,13 @@ ufunmerge/1, rufunmerge/1, ufunsort_1/1, ufunsort_stable/1, ufunsort_rand/1, ufunsort_error/1, + uniq_1/1, uniq_2/1, zip_unzip/1, zip_unzip3/1, zipwith/1, zipwith3/1, filter_partition/1, join/1, otp_5939/1, otp_6023/1, otp_6606/1, otp_7230/1, suffix/1, subtract/1, droplast/1, search/1, hof/1, - enumerate/1, error_info/1]). + enumerate/1, error_info/1]). %% Sort randomized lists until stopped. %% @@ -81,10 +82,11 @@ suite() -> all() -> [{group, append}, {group, key}, - {group,sort}, + {group, sort}, {group, usort}, {group, keysort}, {group, ukeysort}, + {group, uniq}, {group, funsort}, {group, ufunsort}, {group, sublist}, @@ -120,6 +122,7 @@ groups() -> [flatten_1, flatten_2, flatten_1_e, flatten_2_e]}, {tickets, [parallel], [otp_5939, otp_6023, otp_6606, otp_7230]}, {zip, [parallel], [zip_unzip, zip_unzip3, zipwith, zipwith3]}, + {uniq, [parallel], [uniq_1, uniq_2]}, {misc, [parallel], [reverse, member, dropwhile, takewhile, filter_partition, suffix, subtract, join, hof, droplast, search, enumerate, error_info]} @@ -2783,3 +2786,22 @@ do_error_info(L0) -> NYI = [{F,lists:duplicate(A, '*'),nyi} || {F,A} <- Bifs -- Tests], L = lists:sort(NYI ++ L1), error_info_lib:test_error_info(lists, L, [snifs_only]). + +uniq_1(_Config) -> + [] = lists:uniq([]), + [foo] = lists:uniq([foo]), + ["foo", "bar", "zoo"] = lists:uniq(["foo", "foo", "bar", "foo", "zoo", + "foo", "bar", "zoo"]), + [a, 1, b, 2] = lists:uniq([a, a, a, 1, b, 2, a, 2, 1]), + [<<"home">>, "home"] = lists:uniq([<<"home">>, "home"]), + [3.14159, 2.71828, 3.17] = lists:uniq([3.14159, 3.14159, 2.71828, 3.17]), + [42, 42.0] = lists:uniq([42, 42.0, 42, 42.0]), + ok. + +uniq_2(_Config) -> + [] = lists:uniq(fun(X) -> X end, []), + [{42, 1}, {42.0, 99}, {a, 99}] = + lists:uniq(fun(X) -> element(1, X) end, + [{42, 1}, {42.0, 99}, {a, 99}, {a, 1}, {42, 100}]), + [1] = lists:uniq(fun(_) -> whatever end, lists:seq(1, 10)), + ok. -- 2.34.1
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor