`
jjchen_lian
  • 浏览: 86209 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

erlang列表处理

阅读更多

今天在看erlang并发编程一书,收益良多,看了第一遍的erlang程序设计,大概也就是泛泛的看了一遍,现在看第二遍,发现收获到更多的东西。把今天看到的erlang并发编程一书中的精华整理一下。
尽管一个典型的程序往往会使用很多不同的函数来操作列表,但大多数列表处理函数都是由少数几种模式演变而来。大部分列表处理函数无非就是在干着这些事情:

1:    在一个列表中寻找一个元素,并在找到时做些事情。
2:    对输入列表的每个元素做些事情并构造一个与其结构相同的输出列表。
3:    在遇到列表中的第n个元素时做些事情。
4:    对列表进行扫描,并构造一个或一组与原列表相关的新列表。

这四句话总结的很好,对于编程,无非就是对程序传入原始数据,然后由程序进行处理最终返回你想得到的最终数据。所以上面erlang的列表处理函数也是遵循这一道路,只不过erlang相比其他语言,显得更加的灵活,更需要动脑筋。

1):搜索列表元素

search(X, [X|T]) ->
    ... do something ...
    ...;
search(X, [_|T]) ->
    search(X, T);
search(X, []) ->
    ... didn't find it ...


 


第一种情况匹配的是找到了我们所感兴趣的项的情形。第二种情况在列表的头部不是我们所感兴趣的项时匹配,这时将接着处理列表的尾部。最后一种情况匹配的是列表元素耗尽的情形。
2):构建同构列表

isomorphic([X|T]) ->
    [something(X)|isomorphic(T)];
isomorphic([]) ->
    [].


 


在erlang的世界里,处处是递归,相信你也体会的到了,这里无非就是把列表的每个元素取出来,然后再对元素进行处理,然后又生成新的列表。
比如我们想写一个将给定列表中的所有元素翻倍的函数:

double([H|T]) ->
    [2 * H | double(T)];
double([]) ->
    [].
> lists1:double([1,7,3,9,12]).
[2,14,6,18,24]


 

事实上这种手法只能作用于列表的最上层,因此如果我们想遍历列表的所有层次,我们就得将函数定义修改如下:

double([H|T]) when integer(H)->
    [2 * H | double(T)];
double([H|T]) when list(H) ->
    [double(H) | double(T)];
double([]) ->
    [].


 


后一个版本就可以成功遍历深层的嵌套列表了:

> lists1:double([1,2,[3,4],[5,[6,12],3]]).
[2,4,[6,8],[10,[12,24],6]]


 

3):计数
不知大家有没有考虑在erlang语言中如何实现for循环的功能,这其实就是要用到erlang的技术功能。

count(Terminal, L) ->
    ... do something ...;
count(N, [_|L]) ->
    count(N-1, L).


 


则返回列表中第n个元素(假设其存在)的函数可以写成:

nth(1, [H|T]) ->
    H;
nth(N, [_|T]) ->
    nth(N - 1, T).


 


这种递减至一个终止条件的计数方式往往要由于递增计数。为了说明这一点,考虑同样是返回第n个元素但是采用递增计数的函数nth1:

nth1(N, L) ->
    nth1(1, N, L).
nth1(Max, Max, [H|_]) ->
    H;
nth1(N, Max, [_|T]) ->
    nth1(N+1, Max, T).


 


是不是顿时感觉到递归的牛B之处了吧。以前在学数据结构时,我就想过递归是很多算法的母亲,比如搜索,动态规划,树,图等等。
4):收集列表元素
现在我们希望对一个列表中的元素做些动作,生成一个或一组新的列表。对应的模式如下:

collect(L) ->
    collect(L, []).

collect([H|T], Accumulator) ->
    case pred(H) of
        true ->
            collect(T, [dosomething(H)|Accumulator]);
        false ->
            collect(T, Accumulator)
    end;
collect([], Accumulator) ->
    Accumulator.


 



在这里我们引入了一个多出一个参数的辅助函数,多出的这个参数用于存储最终要被返回给调用方的列表。
借助这样一种模式,举个例子,我们可以写这样的一个函数:计算输入列表的所有偶元素的平方并删除所有奇元素:

funny(L) ->
    funny(L, []).

funny([H|T], Accumulator) ->
    case even(H) of
        true -> funny(T, [H*H|Accumulator]);
        false -> funny(T, Accumulator)
    end;
funny([], Accumulator) ->
    Accumulator.


 


于是有:

> lists:funny([1,2,3,4,5,6])
[36,16,4]


 


刚接触erlang,我感觉自己的思维方式发生了蛮大的变化,发现写erlang很爽

 

出自:http://svn.liancheng.info/cpie-cn/trunk/.build/html/part-i/chapter-3.html#id10

分享到:
评论

相关推荐

    erlang编程 Introducing Erlang

    Erlang的语法简洁,支持模式匹配、函数式编程、列表处理和递归等特性。它的动态类型系统和强大的类型推断让代码更加灵活。 Simon St. Laurent的《Introducing Erlang》这本书深入浅出地介绍了这些概念,是学习...

    erlang_版本24.3.4.4

    - **Erlang的数据类型**:包括原子(atom)、整数、浮点数、字符串、列表、元组、位串等。 - **Pattern Matching**:Erlang的匹配操作符`=`允许在函数调用、case语句和receive语句中进行模式匹配。 熟悉这些概念和...

    xiandiao_erlang_Erlang课后习题_

    1. **理解基本语法**:通过解决课后习题,学习者可以熟悉Erlang的基本语法,如变量、函数定义、模式匹配、列表操作等。 2. **掌握并发编程**:习题可能包含创建和管理Erlang进程、实现进程间的消息传递,帮助学习者...

    erlang压缩包.rar

    - **列表处理**:Erlang提供了强大的列表处理功能,如`hd`(head)和`tl`(tail)用于获取列表的第一元素和剩余部分,以及`lists`模块的众多函数。 - **递归**:由于Erlang的进程特性,递归是常见的编程方式,尤其在...

    erlang资源

    1. **Erlang语法**:涵盖基本的变量、数据类型(如原子、列表、元组和二进制)、控制结构(如case表达式和if语句)以及函数定义。 2. **函数式编程概念**:Erlang是纯函数式语言,书中可能会介绍函数式编程的基本...

    Erlang_CNode用户指

    3. **Erlang数据类型和API**:介绍CNode API,包括如何在C中表示和操作Erlang的数据类型(如整数、原子、列表等),以及如何调用Erlang函数和处理返回结果。 4. **进程通信**:阐述如何在CNode中创建Erlang进程,...

    erlang趣学指南

    Erlang还提供了多种常用数据结构,比如元组、列表、字典、集合等,这些数据结构是构建复杂数据类型的基础。 并行编程是Erlang的一大亮点,它允许开发者使用轻量级的进程来执行并行操作,每个进程都是独立的,并拥有...

    erlang23.2版windows64位.zip

    在压缩包子文件的文件名称列表中,我们看到"otp_win64_23.2.exe",这是一个可执行文件,代表Open Telecom Platform (OTP)的Windows 64位版本,OTP是Erlang生态系统的核心部分,包含了开发、调试和运行Erlang应用程序...

    erlang程序设计相关例子程序

    6. **mylists.beam** - 类似于lib_misc,这个模块可能包含了对Erlang列表的特定操作,如过滤、映射、归约等,这些都是函数式编程中的常见操作。 7. **extract.beam** - 可能涉及数据提取或解析功能,例如从文件、...

    erlang中文基础教程

    2. **列表**:Erlang中的列表用方括号包围,可以包含不同类型的数据。 3. **模式匹配**:Erlang的函数调用和case语句都支持模式匹配,方便数据处理。 4. **函数**:Erlang的函数定义使用`fun`关键字,函数体可以是...

    Erlang与Mysql对接

    5. **处理结果**:Erlang驱动将MySQL的查询结果转换为Erlang的数据结构,如列表或元组,以便于进一步处理。你需要遍历这些结果并根据需要进行操作。 6. **事务处理**:如果需要确保一组SQL操作的原子性,可以使用...

    erlang 程序设计 源码

    - **数据结构的使用**:Erlang的列表、元组、映射等数据结构在源码中的应用。 - **模式匹配和函数定义**:了解如何通过模式匹配来简化代码,以及函数多态性的实现。 - **OTP库的使用**:观察源码中是如何利用OTP提供...

    Erlang编程

    - **服务器**:服务器作为并发处理的重要场景,Erlang能提供稳定的并发服务。 #### 重点知识 1. **并发的必要性**: - 现实世界是并行的,现实生活中的对象和活动往往需要同时进行,要想编写程序模拟现实世界的...

    Erlang游戏.zip

    8. **数据结构**:虽然Erlang的原生数据结构相对简单(如列表、元组和映射),但它们在处理游戏数据时仍非常高效。例如,元组用于存储固定大小的游戏状态,映射则适用于动态属性的管理。 9. **并发原语**:Erlang的...

    Concurrent Programming in ERLANG (P1-90)

    除了内置函数外,Erlang还支持许多常用的列表处理函数,如`append`(合并列表)、`reverse`(反转列表)等。这些函数通常被用来进行更高级别的数据操作。 **3.3 示例** 通过具体的示例,可以更好地理解如何在实际...

    某流水过千W的erlang游戏后端

    5. **高效的数据结构**:Erlang的列表、二元组和散列表等数据结构提供了高效的操作,便于快速处理游戏中的各种数据,如玩家信息、游戏状态等。 6. **OTP(Open Telecom Platform)框架**:OTP提供了一套标准库和...

    Programming Erlang

    首先,书中会介绍Erlang的简单数据类型,如原子(atom)、整数、浮点数、字符串和列表,以及如何进行基本的运算和比较。然后,读者将学习到Erlang的函数式编程思想,包括函数定义、模式匹配、匿名函数(也称为闭包)...

    erlang聊天室源码

    5. **状态管理模块**:保存聊天室的状态,如在线用户列表、历史记录等,可能采用了Erlang的分布式数据库如Mnesia来存储。 在源码中,你可能会看到Erlang的并发特性如`spawn`和`receive`表达式,它们允许创建和管理...

    erlang-java聊天

    3. **连接管理**:Erlang服务器需要维护一个客户端连接列表,每当接收到新的连接请求时,都会创建一个新的Erlang进程来处理。Java客户端在连接成功后,会维持一个持久的连接,用于收发消息。 **测试与调试** 在开发...

    erlang mysql

    4. **结果处理**:执行查询后,Erlang 库会将结果集转换为 Erlang 数据结构,如列表或记录,以便于程序处理。结果处理可能包括遍历记录、转换数据类型或执行其他业务逻辑。 5. **事务处理**:Erlang MySQL 驱动还...

Global site tag (gtag.js) - Google Analytics