Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:19
erlang
3271-Add-map-conversion-functions-to-proplists....
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 3271-Add-map-conversion-functions-to-proplists.patch of Package erlang
From 000eef428f7c239b3c4e76b23ea3c578d6bf5219 Mon Sep 17 00:00:00 2001 From: Maria-12648430 <maria-12648430@gmx.net> Date: Fri, 11 Dec 2020 17:03:56 +0100 Subject: [PATCH 1/2] Add map conversion functions to proplists --- lib/stdlib/doc/src/proplists.xml | 32 ++++++++++++++ lib/stdlib/src/proplists.erl | 57 ++++++++++++++++++++++++- lib/stdlib/test/proplists_SUITE.erl | 65 ++++++++++++++++++++++++++++- 3 files changed, 151 insertions(+), 3 deletions(-) diff --git a/lib/stdlib/doc/src/proplists.xml b/lib/stdlib/doc/src/proplists.xml index f59b6eda17..05c02cc3be 100644 --- a/lib/stdlib/doc/src/proplists.xml +++ b/lib/stdlib/doc/src/proplists.xml @@ -137,6 +137,14 @@ expand([{{foo, true}, [bar, baz]}], [{foo, false}, fie, foo, fum])</code> </desc> </func> + <func> + <name name="from_map" arity="1"/> + <fsummary></fsummary> + <desc> + <p>Converts the map <c><anno>Map</anno></c> to a property list.</p> + </desc> + </func> + <func> <name name="get_all_values" arity="2"/> <fsummary></fsummary> @@ -364,6 +372,30 @@ split([{c, 2}, {e, 1}, a, {c, 3, 4}, d, {b, 5}, b], [a, b, c])</code> </desc> </func> + <func> + <name name="to_map" arity="1"/> + <fsummary></fsummary> + <desc> + <p>Converts the property list <c><anno>List</anno></c> to a map.</p> + <p>Shorthand atom values in <c><anno>List</anno></c> will be expanded + to an association of the form <c>Atom => true</c>. Tuples of the + form <c>{Key, Value}</c> in <c><anno>List</anno></c> will be + converted to an association of the form <c>Key => Value</c>. + Anything else will be silently ignored.</p> + <p>If the same key appears in <c><anno>List</anno></c> multiple + times, the value of the one appearing nearest to the head of + <c><anno>List</anno></c> will be in the result map, that is + the value that would be returned by a call to + <c>get_value(Key, List)</c>.</p> + <p><em>Example:</em></p> + <code type="none"> +to_map([a, {b, 1}, {c, 2}, {c, 3}])</code> + <p>returns:</p> + <code type="none"> +#{a => true, b => 1, c => 2}</code> + </desc> + </func> + <func> <name name="unfold" arity="1"/> <fsummary></fsummary> diff --git a/lib/stdlib/src/proplists.erl b/lib/stdlib/src/proplists.erl index 9216c3bdb3..b92982dae0 100644 --- a/lib/stdlib/src/proplists.erl +++ b/lib/stdlib/src/proplists.erl @@ -35,7 +35,7 @@ lookup_all/2, is_defined/2, get_value/2, get_value/3, get_all_values/2, append_values/2, get_bool/2, get_keys/1, delete/2, substitute_aliases/2, substitute_negations/2, - expand/2, normalize/2, split/2]). + expand/2, normalize/2, split/2, from_map/1, to_map/1]). %% --------------------------------------------------------------------- @@ -668,3 +668,58 @@ split([], Store, Rest) -> maps_prepend(Key, Val, Dict) -> Dict#{Key := [Val | maps:get(Key, Dict)]}. + +%% --------------------------------------------------------------------- + +%% @doc Converts the property list <code>List</code> to a map. +%% +%% Shorthand atom values in <code>List</code> will be expanded to an +%% association of the form <code>Atom => true</code>. Tuples of the +%% form <code>{Key, Value}</code> in <code>List</code> will be +%% converted to an association of the form <code>Key => Value</code>. +%% Anything else will be silently ignored. +%% +%% If the same key appears in <code>List</code> multiple times, the +%% value of the one appearing nearest to the head of <code>List</code> +%% will be in the result map, that is the value that would be returned +%% by a call to <code>get_value/2</code> with this key. +%% +%% <p>Example:<pre> +%% to_map([a, {b, 1}, {c, 2}, {c, 3}])</pre> +%% returns<pre> +%% #{a => true, b => 1, c => 2}</pre> +%% </p> + +-spec to_map(List) -> Map when + List :: [Shorthand | {Key, Value} | term()], + Map :: #{Shorthand => 'true', Key => Value}, + Shorthand :: atom(), + Key :: term(), + Value :: term(). + +to_map(List) -> + lists:foldr( + fun + ({K, V}, M) -> + M#{K => V}; + (T, M) when 1 =< tuple_size(T) -> + maps:remove(element(1, T), M); + (K, M) when is_atom(K) -> + M#{K => true}; + (_, M) -> + M + end, + #{}, + List + ). + +%% @doc Converts the map <code>Map</code> to a property list. + +-spec from_map(Map) -> List when + Map :: #{Key => Value}, + List :: [{Key, Value}], + Key :: term(), + Value :: term(). + +from_map(Map) -> + maps:to_list(Map). diff --git a/lib/stdlib/test/proplists_SUITE.erl b/lib/stdlib/test/proplists_SUITE.erl index 600fb8845e..64c5e60125 100644 --- a/lib/stdlib/test/proplists_SUITE.erl +++ b/lib/stdlib/test/proplists_SUITE.erl @@ -23,7 +23,7 @@ -export([all/0, suite/0,groups/0, init_per_suite/1, end_per_suite/1, init_per_group/2, end_per_group/2, init_per_testcase/2, end_per_testcase/2, - examples/1]). + examples/1, map_conversion/1]). init_per_testcase(_Case, Config) -> Config. @@ -36,7 +36,7 @@ suite() -> {timetrap,{minutes,5}}]. all() -> - [examples]. + [examples, map_conversion]. groups() -> []. @@ -77,4 +77,65 @@ examples(_Config) -> NegListRes = [{foo, false}, {foo, false}, foo, foo, foo], NegListRes = proplists:substitute_negations([{no_foo, foo}], NegList), + true = #{a => true, b => 1, c => 2} =:= proplists:to_map([a, {b, 1}, {c, 2}, {c, 3}]), + + ok. + +map_conversion(_Config) -> + %% Simple tests. + true = #{} =:= proplists:to_map([]), + true = #{a => true, b => true} =:= proplists:to_map([a, b]), + true = #{a => true, b => true} =:= proplists:to_map([b, a]), + true = #{a => 1, b => true} =:= proplists:to_map([{a, 1}, b]), + true = #{a => 1, b => true} =:= proplists:to_map([b, {a, 1}]), + true = #{a => 1, b => 2} =:= proplists:to_map([{a, 1}, {b, 2}]), + true = #{a => 1, b => 2} =:= proplists:to_map([{b, 2}, {a, 1}]), + true = #{b => true} =:= proplists:to_map(["a", b]), + true = #{b => true} =:= proplists:to_map([b, "a"]), + true = #{b => true} =:= proplists:to_map([{a}, b]), + true = #{b => true} =:= proplists:to_map([b, {a}]), + true = #{b => true} =:= proplists:to_map([{a, 1, 2}, b]), + true = #{b => true} =:= proplists:to_map([b, {a, 1, 2}]), + + %% Ensure that maps:get/3 using the created map yields the same + %% results as proplists:get_value/3 on the original proplist does, + %% and that proplists:get_value/3 on a proplist created from the + %% map yields the same results as proplists:get_value/3 on the + %% original proplist, ie they either all return the same `Value', + %% or they all return the `Default' given as respective third argument. + Default1 = make_ref(), + Default2 = make_ref(), + Default3 = make_ref(), + InList=[a, b, {a, 1}, {}, {a}, {a, 1, 2}, "foo"], + lists:foreach( + fun (L1) -> + LKs = proplists:get_keys(L1), + M = proplists:to_map(L1), + L2 = proplists:from_map(M), + [] = maps:keys(M) -- LKs, + [] = proplists:get_keys(L2) -- LKs, + lists:foreach( + fun (K) -> + case + { + maps:get(K, M, Default1), + proplists:get_value(K, L1, Default2), + proplists:get_value(K, L2, Default3) + } + of + {V, V, V} -> true; + {Default1, Default2, Default3} -> true + end + end, + LKs + ) + end, + [[A, B, C, D, E, F, G] || A <- InList, + B <- InList -- [A], + C <- InList -- [A, B], + D <- InList -- [A, B, C], + E <- InList -- [A, B, C, D], + F <- InList -- [A, B, C, D, E], + G <- InList -- [A, B, C, D, E, F]] + ), ok. -- 2.26.2
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