elixir教程:递归和枚举

news/2024/5/19 2:13:07 标签: elixir, erlang, 递归, 循环, 枚举

文章目录

递归

由于在Elixir中,变量是不可变的,从而类似i++这种自增指令是没法实现的,也就没法进行循环。但作为一种编程语言来说,循环又是必不可少的一种流程控制手段,而在elixir中,实现循环的第一方法,就是递归

递归,就是调用自身的函数,下面举一个简单的计算阶乘的例子

elixir"># Test.ex
defmodule Test do
   def fac(n) when n <= 1 do
      1
   end

   def fac(n) do
      n*fac(n-1)
   end
end

测试结果如下

elixir">> Test.fac(5)
120

递归实现循环

想用递归实现循环,则至少需要有一个用于终止循环的标记,例如,若想打印所有小玉N的整数,用for循环写一个伪代码就是

for(i=0; i<=N; i++) print(i)

而在elixir中,若用递归来改写这个循环,则代码如下

elixir"># 在Test.ex的defmodule中添加下列内容
def printNum(i, n) do
   IO.puts i
   if i < n do
      printNum(i+1, n)
   end
end

其运行结果为

elixir">iex(1)> Test.printNum(1,5)
1
2
3
4
5
nil

列表和尾递归

在介绍模式匹配时,也附带介绍了elixir中的一种键值对数据结构,即关键字列表、表单,这是因为模式匹配是elixir中最核心的一种编程理念。但对于普通程序员来说,列表显然要比关键字列表更为基础。

elixir中,列表的创建方式非常简单,只需用方括号框起来就可以,而且列表中不限定数据类型。

elixir">> lst = [1,2,"a","trump"]
[1, 2, "a", "trump"]

之所以在讲解循环的实现方式之后再着重介绍列表,是因为在某些语言中,是支持类似for ... in lst这种循环的,换言之,列表是一种天然的适合迭代的数据结构。

针对列表,有一种特殊的迭代方法,即尾递归,下面通过这种思路,实现一个数组求和函数

elixir"># 在Test.ex中添加下列内容
def sumList(lst) do
   sumList(lst, 0)
end

# 尾递归函数
def sumList([head|tail], sumVar) do
   sumList(tail, head + sumVar)
end

def sumList([], sumVar) do
   sumVar
end

调用结果为

elixir">> Test.sumList([1,2,3,4])
10

Enum模块

尽管尾递归用起来并不复杂,但和直接迭代列表相比,仍然是比较复杂的。故而elixir提供了Enum模块,用于处理类似列表这种可枚举的数据结构,从而使得一行代码就可以进行列表求和

elixir">> Enum.sum([1,2,3,4])
10
> Enum.reduce([1,2,3,4], 0, &+/2)
10

Enum.sum相当于是封装好的求和函数,自然没什么好说的,但reduce却是另一种编程逻辑,相当于从0开始,逐次执行+这一二元操作,直到列表被迭代完成。

reduce相比,map可能更容易理解,相当于是把列表中的每个值抽取出来,然后逐个操作,并得到一个新的列表,下面是对列表中每个元素求平方

> Enum.map([1, 2, 3, 4], fn x -> x * 2 end)
[2, 4, 6, 8]

Enum中提供了一系列用于可迭代变量的函数

函数说明
min/max/sum最小值;最大值;求和
all?/any?条件判断
each/map遍历
filter按条件过滤
reduce
sort/uniq排序;去除重复值

其中,eachmap的区别,即前者并不产生新的值,后者产生新值,如果想打印列表中的所有值,就比较推荐Enum.each函数。

filter, all?, any?这三者所需要的函数,返回值应该都是布尔型,下面以erm(x,2)==0作为条件,分别测试一下这三个函数

elixir">iex(7)> Enum.filter([1, 2, 3, 4], fn(x) -> rem(x, 2) == 0 end)
[2, 4]
iex(8)> Enum.any?([1, 2, 3, 4], fn(x) -> rem(x, 2) == 0 end)
true
iex(9)> Enum.all?([1, 2, 3, 4], fn(x) -> rem(x, 2) == 0 end)
false

其中,any?的含义是,只要列表中有符合2的倍数的值,那么就返回trueall?则要求列表中所有值都是2的倍数,才返回true


http://www.niftyadmin.cn/n/468914.html

相关文章

卫星地图应用经典实例项目(7个)

本文会介绍引用一些非常好的卫星地图等相关的应用,一方面给大家增加见识,另一方面会提供一些设计开发的思路以及代码。 文章目录 热气球追踪系统googlemap实现卫星轨迹satvis卫星Cesium系统NASA的worldview系统项目Esri-Satellite-Map基于leaflet的卫星轨迹绘制项目地球当前…

【Shell1】shell语法,ssh/build/scp/upgrade,环境变量

文章目录 1.shell语法&#xff1a;shell是用C语言编写的程序&#xff0c;是用户使用Linux的桥梁&#xff0c;硬件>内核(os)>shell>文件系统1.1 变量&#xff1a;readonly定义只读变量&#xff0c;unset删除变量1.2 函数&#xff1a;shell脚本传递的参数中包含空格&…

文献学习-联合抽取-Joint entity and relation extraction based on a hybrid neural network

目录 1、Introduction 2、Related works 2.1 Named entity recognition 2.2 Relation classification 2.3 Joint entity and relation extraction 2.4 LSTM and CNN models On NLP 3、Our method 3.1 Bidirectional LSTM encoding layer 3.2 Named entity recogniton …

基于 Redis 手写一个“秒杀”

博主介绍&#xff1a; ✌博主从事应用安全和大数据领域&#xff0c;有8年研发经验&#xff0c;5年面试官经验&#xff0c;Java技术专家✌ Java知识图谱点击链接&#xff1a;体系化学习Java&#xff08;Java面试专题&#xff09; &#x1f495;&#x1f495; 感兴趣的同学可以收…

计算机图形学 期末复习 微课版 孔令德 八、真实感图形 期末复习

颜色模型 RGB颜色模型添加一个a(alpha)分量代表透明度&#xff0c;形成RGBA模型。 光照模型 简单光照模型 简单光照模型假定光源为点光源&#xff0c;入射关仅由红、绿、蓝3种不同波长的光组成&#xff1b;物体为非透明物体&#xff0c;物体表面所呈现的颜色仅由反射光决定&…

Mybatis源码篇:Mybatis初始化过程分析

文章目录 1. Mybatis初始化过程简述2. Mybatis初始化源码分析2.1 Mybatis初始化时序图2.2 源码分析2.2.1 SqlSessionFactoryUtil测试类代码2.2.2 SqlSessionFactoryBuilder源码2.2.3 XMLConfigBuilder源码2.2.4 SqlSessionFactory相关属性2.2.5 SqlSession相关属性 3. 总结4. 使…

Docker 安装 Nginx,并实现负载均衡

1、获取 nginx 的镜像 # 默认是latest版本docker pull nginx 2、运行 nginx 容器 docker run --name nginx-80 -p 80:80 --rm -d nginx# --name nginx-80 设定容器的名称# -p 80:80 端口进行映射&#xff0c;将本地的80端口映射到容器内部的80端口# --rm 表示容器退出后直接…

Jenkins在Ubuntu的安装问题

使用apt安装没有成功&#xff0c;各种报错。最后使用了离线安装方式。 1、安装jdk。和之前的安装jdk无异&#xff0c;增加一步 添加一个软链接 sudo ln -s /path/to/java/home/bin/java /usr/bin/java 2、下载deb包&#xff0c;然后安装 2.1、前置步骤&#xff0c;安装可能…