Erlang--proplists结构解析
- 5> proplists:get_value(1,[{1,a},{1.0,b},{1,c}]).
- a
- 6> proplists:append_values(1,[{1,a},{1.0,b},{1,c}]).
- [a,c]
- 8>
规范与压缩

- property({Key, true}) when is_atom(Key) ->
- Key;
- property(Property) ->
- Property.
- 调用的形式:
- 16> proplists:property({a}).
- {a}
- 17> proplists:property({a,true}).
- a

- 10> proplists:compact( [{a, true}, {b, true}, {a, 3}, {c, true}, {a, [4]}]).
- [a,b,{a,3},c,{a,[4]}]

- unfold([P | Ps]) ->
- if is_atom(P) ->
- [{P, true} | unfold(Ps)];
- true ->
- [P | unfold(Ps)]
- end;
- unfold([]) ->
- [].
- 12> proplists:unfold([foo,bar,test,haha]).
- [{foo,true},{bar,true},{test,true},{haha,true}]
- 13> proplists:unfold([foo,bar,{test,false},haha]).
- [{foo,true},{bar,true},{test,false},{haha,true}]
- 14> proplists:unfold([foo,"zen",bar,{test,false},haha]).
- [{foo,true},"zen",{bar,true},{test,false},{haha,true}]
- 15> proplists:unfold([foo,"zen",23,{test,false},haha]).
- [{foo,true},"zen",23,{test,false},{haha,true}]

proplists 相关操作

- 1> proplists:append_values(a, [{a, [1,2]}, {b, 0}, {a, 3}, {c, -1}, {a, [4]}]).
- [1,2,3,4]
- 2> proplists:append_values(a, [{a, b}, {b, 0}, {a, 3}, {c, -1}, {a, [4]}]).
- [b,3,4]
- 3> proplists:append_values(a, [{a, b}, {b, 0}, {a, 3}, {c, -1}, {a, [[4]]}]).
- [b,3,[4]]
- 1> proplists:append_values(a, [{a, [1,2]}, {"zen", 0}, {a, 3}, {c, -1}, {a, [4]}
- ]).
- [1,2,3,4]
- 2> proplists:append_values(a, [{a, [1,2]},b]).
- [1,2]
- 3> proplists:append_values(b, [{a, [1,2]},b]).
- [true]
- 4>

- %% delete(Key, List) -> List
- 18> proplists:delete(a, [{a, true}, {b, true}, {a, 3}, {c, true}, {a, [4]}]).
- [{b,true},{c,true}]
- 10> proplists:compact( [{a, true}, {b, true}, {a, 3}, {c, true}, {a, [4]}]).
- [a,b,{a,3},c,{a,[4]}]
get_all_values 获取所有等于Key值的数据项:
- 8> proplists:get_all_values(a, [{a, [1,2]}, {"zen", 0}, {a, 3}, {c, -1}, {a, [4]
- }]).
- [[1,2],3,[4]]
- 9>

- get_bool(Key, [P | Ps]) ->
- if is_atom(P), P =:= Key -> true;
- tuple_size(P) >= 1, element(1, P) =:= Key ->
- case P of
- {_, true} ->
- true;
- _ ->
- %% Don't continue the search!
- false
- end;
- true ->
- get_bool(Key, Ps)
- end;
- get_bool(_Key, []) ->
- false.
- 9> proplists:get_bool(a, [{a, [1,2]}, {"zen", 0}, {a, 3}, {c, -1}, {a, [4]}]).
- false
- 10> proplists:get_bool(a, [{a, [1,2]}, {"zen", 0}, {a, 3},a, {c, -1}, {a, [4]}]).
- false
- 11> proplists:get_bool(a, [a,{a, [1,2]}, {"zen", 0}, {a, 3},a, {c, -1}, {a, [4]}]).
- true
- 12> proplists:get_bool(a, [{a,true},{a, [1,2]}, {"zen", 0}, {a, 3},a, {c, -1}, {a, [4]}]).
- true
- 13> proplists:get_bool(a, [{a,false},{a, [1,2]}, {"zen", 0}, {a, 3},a, {c, -1},{a, [4]}]).
- false
- 14> proplists:get_bool(q, [{a,true},{a, [1,2]}, {"zen", 0}, {a, 3},a, {c, -1}, {a, [4]}]).
- false
- 15> proplists:get_bool(q, ["abc",{a,true},{a, [1,2]}, {"zen", 0}, {a, 3},a, {c,-1}, {a, [4]}]).
- false
- 16> proplists:get_bool("abc", ["abc",{a,true},{a, [1,2]}, {"zen", 0}, {a, 3},a,{c, -1}, {a, [4]}]).
- false
- 17> proplists:get_bool("abc", [{"abc",true},{a,true},{a, [1,2]}, {"zen", 0}, {a,
- 3},a, {c, -1}, {a, [4]}]).
- true

- 18> proplists:get_keys([{"abc",true},{a,true},{a, [1,2]}, {"zen", 0}, {a, 3},a,{c, -1}, {a, [4]}]).
- ["zen",a,c,"abc"]
- 19> proplists:get_keys([{a,true},{a,true},{a, [1,2]}, {"zen", 0}, {a, 3},a, {c,-1}, {a, [4]}]).
- ["zen",a,c]

- get_value(Key, [P | Ps], Default) ->
- if is_atom(P), P =:= Key ->
- true;
- tuple_size(P) >= 1, element(1, P) =:= Key ->
- case P of
- {_, Value} ->
- Value;
- _ ->
- %% Don</code>t continue the search!
- Default
- end;
- true ->
- get_value(Key, Ps, Default)
- end;
- get_value(_Key, [], Default) ->
- Default.
- 3> proplists:get_value([a,b], ["packet",[a,b],"login",22,2,s,f] , "none").
- "none"
- 4> proplists:get_value("login", ["packet",[a,b],"login",22,2,s,f] , "none").
- "none"
- 5> proplists:get_value(login, ["packet",[a,b],"login",22,2,s,f] , "none").
- "none"
- 1> proplists:get_value([a,b], ["packet",{[a,b],bingo},"login",22,2,s,f] , "none").
- bingo
- 2> proplists:get_value(s, ["packet",{[a,b],bingo},"login",22,2,s,f] , "none").
- true
- 3>

- 6> proplists:lookup(a, [{a, b}, {b, 0}, {a, 3}, {c, -1}, {a, [[4]]}]).
- {a,b}
- 7> proplists:lookup(a, [{a,1},{a, b}, {b, 0}, {a, 3}, {c, -1}, {a, [[4]]}]).
- {a,1}
- 8>
- 8> proplists:lookup_all(a, [{a,1},{a, b}, {b, 0}, {a, 3}, {c, -1}, {a, [[4]]}]).
- [{a,1},{a,b},{a,3},{a,[[4]]}]
- 6> proplists:is_defined(s, ["packet",{s,kill},{[a,b],bingo},"login",22,2,s,f]).
- true
- 7> proplists:is_defined(p, ["packet",{s,kill},{[a,b],bingo},"login",22,2,s,f]).
- false
- 8>
- 9> proplists:split([{c, 2}, {e, 1}, a, {c, 3, 4}, d, {b, 5}, b], [a, b, c]).
- {[[a],[{b,5},b],[{c,2},{c,3,4}]],[{e,1},d]}
- 10> proplists:split([{c, 2}, {c,23},{a,false},{e, 1}, a, {c, 3, 4}, d, {b, 5}, b
- ], [a, b, c]).
- {[[{a,false},a],[{b,5},b],[{c,2},{c,23},{c,3,4}]],[{e,1},d]}
- 11>
单独一组

- 8> proplists: expand([{foo, [bar, baz]}],[fie, foo, fum]).
- [fie,bar,baz,fum]
- 9> proplists: expand([{foo, [bar, baz]},{fie,ok},{fum,100}],[fie, foo, fum]).
- [ok,bar,baz,100]
- 10> proplists: expand([{foo, [bar, baz]},{fie,[[ok]]},{fum,"100"}],[fie, foo, fum]).
- [[ok],bar,baz,49,48,48]
- 12> proplists: expand([{"fie",23},{1,{1}},{1.0,{29}},{foo, [bar, baz]},{fie,[[ok]]},{fum,"100"}],["fie",1, foo, fum]).
- [102,105,101,1,bar,baz,49,48,48]
- 13> ${.
- 123
- 14> [102,105,101].
- "fie"
- 15>

- 1> proplists:substitute_aliases([{zen,"ligaoren"},{0,zero}],[zen,{zen,zen},{abc,zen},{zen,tick},0,{0,1},{23,0}]).
- [{"ligaoren",true},{"ligaoren",zen},{abc,zen},{"ligaoren",tick},0,{zero,1},{23,0}]
- 2>

- 2> proplists:substitute_negations([{zen,"ligaoren"},{0,zero}],[zen,{zen,zen},{abc,zen},{zen,tick},0,{0,1},{23,0}]).
- [{"ligaoren",false},{"ligaoren",true},{abc,zen},{"ligaoren",true},0,zero,{23,0}]
- 3> proplists:substitute_negations([{zen,"ligaoren"},{0,zero}],[zen,{zen,zen},{abc,zen},{zen,tick},0,{0,true},{23,0}]).
- [{"ligaoren",false},{"ligaoren",true},{abc,zen},{"ligaoren",true},0,{zero,false},{23,0}]
- 4> proplists:substitute_negations([{zen,"ligaoren"},{0,zero}],[zen,{zen,zen},{abc,zen},{zen,tick},0,{0,false},{23,0}]).
- [{"ligaoren",false},{"ligaoren",true},{abc,zen},{"ligaoren",true},0,zero,{23,0}]


- 2> proplists:normalize( [a,b,c,d,e,f,g],[{aliases, [{b,b2},{e,email}]} ]).
- [a,b2,c,d,email,f,g]
- 3> proplists:normalize([a,b,c,d,e,f,g],[{aliases, [{b,b2},{e,email}]} ]).
- [a,b2,c,d,email,f,g]
- 4> proplists:normalize([a,b,c,d,e,f,g],[{aliases, [ {negations, [a,f]}]} ]).
- [a,b,c,d,e,f,g]
- 5> proplists:normalize([a,b,c,d,e,f,g],[ {expand, [{d,do_it_by_yourself},{g,1000}]}]).
- [a,b,c,do_it_by_yourself,e,f,1000]

应用举例

- 6> test:module_info(compile).
- [{options,[{outdir,"/zen/temp"}]},
- {version,"4.8"},
- {time,{2012,6,15,2,3,23}},
- {source,"/zen/temp/test.erl"}]
- 7> proplists:get_value(time,test:module_info(compile)).
- {2012,6,15,2,3,23}
- 8>


- parse_form_outer(eof, _, Acc) ->
- lists:reverse(Acc);
- parse_form_outer({headers, H}, FileHandler, State) ->
- {"form-data", H1} = proplists:get_value("content-disposition", H),
- Name = proplists:get_value("name", H1),
- Filename = proplists:get_value("filename", H1),
- case Filename of
- undefined ->
- fun (Next) ->
- parse_form_value(Next, {Name, []}, FileHandler, State)
- end;
- _ ->
- ContentType = proplists:get_value("content-type", H),
- Handler = FileHandler(Filename, ContentType),
- fun (Next) ->
- parse_form_file(Next, {Name, Handler}, FileHandler, State)
- end
- end.

解析选项一例:

- %%% 18> proplists:lookup(loop,[{ip, "127.0.0.1"},{loop, {mochiweb_http, default_body}}]).
- %%% {loop,{mochiweb_http,default_body}}
- parse_options(Options) ->
- {loop, HttpLoop} = proplists:lookup(loop, Options),
- Loop = fun (S) ->
- ?MODULE:loop(S, HttpLoop)
- end,
- Options1 = [{loop, Loop} | proplists:delete(loop, Options)],
- mochilists:set_defaults(?DEFAULTS, Options1).

最后:估计90%的情况下,我们只使用proplists:get_value : )
2012-8-22更新
proplists:get_value的性能要比lists:keyfind差很多,
lists的下面几个方法都是BIF实现:%% Bifs: keymember/3, keysearch/3, keyfind/3
而proplists:get_value是Erlang实现,我觉得这是产生性能差异的根本原因;
下面有一个相关讨论基本上是同样的判断: http://www.ostinelli.net/erlang-listskeyfind-or-proplistsget_value/

- -module(pvsl).
- -define(LIST_SIZES, [10000, 100000, 1000000]).
- -define(RETRIES, 1000).
- -compile(export_all).
- start() ->
- % test for different list sizes
- lists:foreach(fun(N) -> test_list(N) end, ?LIST_SIZES).
- test_list(ListSize) ->
- % generate a list of size ListSize of {Key, Val} entries
- KeyList = [{K, K} || K <- lists:seq(1, ListSize)],
- % test this list against both functions
- lists:foreach(fun(Type) -> get_val(Type, now(), KeyList, ListSize, ?RETRIES) end,
- [proplists, lists]).
- % test getting values, compute necessary time and output print results
- get_val(Type, Start, _KeyList, ListSize, 0) ->
- T = timer:now_diff(now(), Start),
- io:format("computed ~p random key searches on a ~p-sized list in ~p ms using ~p~n",
- [?RETRIES, ListSize, T/1000, Type]);
- get_val(proplists, Start, KeyList, ListSize, Tries) ->
- proplists:get_value(random:uniform(ListSize), KeyList),
- get_val(proplists, Start, KeyList, ListSize, Tries - 1);
- get_val(lists, Start, KeyList, ListSize, Tries) ->
- lists:keyfind(random:uniform(ListSize), 1, KeyList),
- get_val(lists, Start, KeyList, ListSize, Tries - 1).
- I ran this test on my MacBook Pro, Intel Core i5 2.4GHz with 4GB Memory, and Erlang R13B04, with Kernel Polling enabled. These are the results.
- roberto$ erl +K true +P 1000000
- Erlang R13B04 (erts-5.7.5) [source] [smp:4:4] [rq:4] [async-threads:0] [hipe] [kernel-poll:true]
- Eshell V5.7.5 (abort with ^G)
- 1> c(pvsl).
- {ok,pvsl}
- 2> pvsl:start().
- computed 1000 random key searches on a 10000-sized list in 323.373 ms using proplists
- computed 1000 random key searches on a 10000-sized list in 12.897 ms using lists
- computed 1000 random key searches on a 100000-sized list in 3273.973 ms using proplists
- computed 1000 random key searches on a 100000-sized list in 130.592 ms using lists
- computed 1000 random key searches on a 1000000-sized list in 34131.905 ms using proplists
- computed 1000 random key searches on a 1000000-sized list in 2050.627 ms using lists
- ok
- 3>

Erlang--proplists结构解析的更多相关文章
- iOS沙盒目录结构解析
iOS沙盒目录结构解析 原文地址:http://blog.csdn.net/wzzvictory/article/details/18269713 出于安全考虑,iOS系统的沙盒机制规定每个应 ...
- H.264码流结构解析
from:http://wenku.baidu.com/link?url=hYQHJcAWUIS-8C7nSBbf-8lGagYGXKb5msVwQKWyXFAcPLU5gR4BKOVLrFOw4bX ...
- Oracle的rowid结构解析
SQL> select rowid,deptno from dept; ROWID DEPTNO ------------------ ---------- A ...
- EXT 结构解析
EXT Demo 结构解析 创建项目 sencha -sdk F:\lib\ext-6.0.0 generate app demo F:\demo 预览项目 执行命令 sencha app build ...
- ionic项目结构解析
ionic项目结构解析 原始结构 创建一个IonicDemo项目 'ionic start IonicDemo sidemenu' 这种结构多模块开发比较麻烦,因为view跟controller分开路 ...
- Redis源码剖析--源码结构解析
请持续关注我的个人博客:https://zcheng.ren 找工作那会儿,看了黄建宏老师的<Redis设计与实现>,对redis的部分实现有了一个简明的认识.在面试过程中,redis确实 ...
- InfluxDB源码目录结构解析
操作系统 : CentOS7.3.1611_x64 go语言版本:1.8.3 linux/amd64 InfluxDB版本:1.1.0 influxdata主目录结构 [root@localhost ...
- [转帖]认识固态:SSD硬盘内外结构解析
认识固态:SSD硬盘内外结构解析 来自: 中关村在线 收藏 分享 邀请 固态硬盘(Solid State Drive),简称固态盘(SSD),是用固态电子存储芯片阵列而制成的硬盘,由控制单元和存储单元 ...
- redis源代码结构解析
看了黄建宏老师的<Redis设计与实现>,对redis的部分实现有了一个简明的认识: 之前面试的时候被问到了这部分的内容,没有关注,好在还有时间,就把Redis的源码看了一遍. Redis ...
- MBR结构解析与fdisk的bash实现
一.MBR结构解析 首先我们先介绍一些MBR的基本知识基础,再晾图片分析. MBR主要分为三大块各自是: 1.载入引导程序(446K) 2.分区表(64k) 3.标志结束位(2k) 载入引导程序:内容 ...
随机推荐
- javascript 基础
javascript概述: javascript历史: * 1992年Nombas开发出C-minus-minus(C--)的嵌入式脚本语言(最初绑定在CEnvi软件中).后将其改名ScriptEas ...
- Chrome 开发工具之Network
经常会听到比如"为什么我的js代码没执行啊?","我明明发送了请求,为什么反应?","我这个网站怎么加载的这么慢?"这类的问题,那么问题既然 ...
- BZOJ1923: [Sdoi2010]外星千足虫
传送门 高斯消元求解Xor方程. 这个方程很容易换成xor的方程.然后用高斯消元搞就行了. 用bitset实现这个非常方便. //BZOJ 1923 //by Cydiater //2016.11.3 ...
- logstash-5.0同步mysql
环境 Windows10企业版X64 安装logstash-input-jdbc插件 进入logstash/bin/目录,命令: logstash-plugin install logstash-in ...
- React项目(二):生命游戏
引子 这是16年最后的一个练手项目,一贯的感觉就是,做项目容易,写说明文档难.更何况是一个唤起抑郁感觉的项目,码下的每个字,心就如加了一个千斤的砝码. 2016年,有些事我都已忘记,但我现在还记得.2 ...
- Python连接MySQL
win10.Python2.7.Pycharm import MySQLdb conn = MySQLdb.Connect( host = '127.0.0.1', port = 3306, user ...
- 欢迎来到Joyful Physics博客
本博客主要包括以下内容: 物理课程 预计会涵盖非物理专业普通物理.物理专业普通物理.理论物理(四大力学).凝聚态物理,会特别关注软物质物理,因为博主是做软物质物理的. 软硬科普 软科普写给非专业人士. ...
- Template function 函数模板用法
#include<iostream> using namespace std; const double PI = 3.1415926; template <class T> ...
- C#发送邮件异常:根据验证过程,远程证书无效
今天在做发送邮件功能时,开始用qq邮箱和163邮箱都可以正常发送,后再改用我公司的邮箱和smtp时竟然报错了. 异常提示-----"根据验证过程,远程证书无效",后来通过查询资料解 ...
- WPF中弹出菜单
在WPF里弹出菜单是用Popup,你那个右键的是上下文菜单(也就是快捷菜单). <Grid> <Button x:Name="BtnPop" Width=&quo ...