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 中并不等效,因为它们由不同的类型表示。

列表的长度

为了找到列表的长度,我们使用长度函数,如以下程序所示 -

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 标准库提供了大量处理列表的函数。我们将在这里看看其中的一些。您可以在此处查看其余列表

S.号 函数名称和描述
1

删除(列表,项目)

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

2

delete_at(列表,索引)

通过删除指定索引处的值来生成新列表。负索引表示距列表末尾的偏移量。如果索引越界,则返回原始列表。

3

第一个(列表)

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

4

展平(列表)

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

5

insert_at(列表、索引、值)

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

6

最后(列表)

返回列表中的最后一个元素,如果列表为空,则返回 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返回了新元组。存储在元组变量中的原始元组没有被修改,因为 Elixir 数据类型是不可变的。由于不可变,Elixir 代码更容易推理,因为您永远不需要担心特定代码是否会改变您的数据结构。

元组与列表

列表和元组有什么区别?

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

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