Elixir - 列表和元组



(链接)列表

链接列表是存储在内存中不同位置的元素的异构列表,并使用引用进行跟踪。链接列表是函数式编程中特别使用的的数据结构。

Elixir 使用方括号来指定值的列表。值可以是任何类型 -

[1, 2, true, 3]

当 Elixir 看到一个可打印的 ASCII 数字列表时,Elixir 会将其打印为字符列表(字面意思是一个字符列表)。无论何时在 IEx 中看到一个值并且不确定它是什么,都可以使用i函数来检索有关它的信息。

IO.puts([104, 101, 108, 108, 111])

列表中的上述字符都是可打印的。当运行上述程序时,它会产生以下结果 -

hello

也可以使用单引号反向定义列表 -

IO.puts(is_list('Hello'))

当运行上述程序时,它会产生以下结果 -

true

请记住,在 Elixir 中,单引号和双引号表示法并不等效,因为它们由不同的类型表示。

列表长度

要查找列表的长度,我们使用 length 函数,如下面的程序所示 -

IO.puts(length([1, 2, :true, "str"]))

上述程序生成以下结果 -

4

连接和减法

可以使用++--运算符连接和减去两个列表。请考虑以下示例以了解这些函数。

IO.puts([1, 2, 3] ++ [4, 5, 6])
IO.puts([1, true, 2, false, 3, true] -- [true, false])

这将在第一种情况下为您提供连接的字符串,在第二种情况下提供减去的字符串。上述程序生成以下结果 -

[1, 2, 3, 4, 5, 6]
[1, 2, 3, true]

列表的头和尾

头是列表的第一个元素,尾是列表的其余部分。它们可以使用hdtl函数检索。让我们将列表分配给一个变量并检索其头和尾。

list = [1, 2, 3]
IO.puts(hd(list))
IO.puts(tl(list))

这将输出列表的头和尾。上述程序生成以下结果 -

1
[2, 3]

注意 - 获取空列表的头或尾是错误的。

其他列表函数

Elixir 标准库提供了大量用于处理列表的函数。我们将在本文中介绍其中的一些。

序号 函数名称和描述
1

delete(list, item)

从列表中删除给定的项目。返回不包含该项目的列表。如果该项目在列表中出现多次,则仅删除第一次出现的项目。

2

delete_at(list, index)

通过删除指定索引处的值来生成一个新列表。负索引表示从列表末尾的偏移量。如果索引超出范围,则返回原始列表。

3

first(list)

返回列表中的第一个元素,如果列表为空则返回 nil。

4

flatten(list)

展平给定的嵌套列表列表。

5

insert_at(list, index, value)

返回一个在指定索引处插入值的列表。请注意,索引限制为列表长度。负索引表示从列表末尾的偏移量。

6

last(list)

返回列表中的最后一个元素,如果列表为空则返回 nil。

元组

元组也是数据结构,它们在其中存储许多其他结构。与列表不同,它们将元素存储在连续的内存块中。这意味着按索引访问元组元素或获取元组大小是一个快速操作。索引从零开始。

Elixir 使用花括号定义元组。与列表一样,元组可以保存任何值 -

{:ok, "hello"}

元组长度

要获取元组的长度,请使用tuple_size函数,如下面的程序所示 -

IO.puts(tuple_size({:ok, "hello"}))

上述程序生成以下结果 -

2

追加值

要将值追加到元组,请使用 Tuple.append 函数 -

tuple = {:ok, "Hello"}
Tuple.append(tuple, :world)

这将创建并返回一个新的元组:{:ok, "Hello", :world}

插入值

要在给定位置插入值,可以使用Tuple.insert_at函数或put_elem函数。请考虑以下示例以了解相同内容 -

tuple = {:bar, :baz}
new_tuple_1 = Tuple.insert_at(tuple, 0, :foo)
new_tuple_2 = put_elem(tuple, 1, :foobar)

请注意,put_eleminsert_at返回了新的元组。存储在 tuple 变量中的原始元组没有被修改,因为 Elixir 数据类型是不可变的。通过不可变性,Elixir 代码更容易推理,因为您永远不必担心特定代码是否正在就地修改您的数据结构。

元组与列表

列表和元组有什么区别?

列表在内存中以链接列表的形式存储,这意味着列表中的每个元素都保存其值并指向下一个元素,直到到达列表的末尾。我们将每对值和指针称为 cons 单元格。这意味着访问列表的长度是一个线性操作:我们需要遍历整个列表才能确定其大小。更新列表很快,只要我们正在预先添加元素。

另一方面,元组在内存中连续存储。这意味着通过索引获取元组大小或访问元素的速度很快。但是,更新或向元组添加元素代价很高,因为它需要在内存中复制整个元组。

广告