列表和元组( Lists and Tuples)
(Linked) Lists
链表是一个异构的元素列表,它们存储在内存中的不同位置,并通过使用引用来跟踪。 链表是特别用于函数式编程的数据结构。
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]
列表的头部和尾部
head是列表的第一个元素,tail是列表的其余部分。 可以使用函数hd和tl检索它们。 让我们为变量分配一个列表并检索它的头部和尾部。
list = [1, 2, 3]
IO.puts(hd(list))
IO.puts(tl(list))
这将给我们列表的头部和尾部作为输出。 上述程序产生以下结果 -
1
[2, 3]
Note - 获取空列表的头部或尾部是一个错误。
Other List Functions
Elixir标准库提供了许多处理列表的功能。 我们将在这里看看其中一些。 你可以看看这里的其余部分。
S.no. | 功能名称和描述 |
---|---|
1 | delete(list, item) 从列表中删除给定的项目。 返回没有项目的列表。 如果项目在列表中出现多次,则仅删除第一个匹配项。 |
2 | delete_at(list, index) 通过删除指定索引处的值来生成新列表。 负指数表示从列表末尾的偏移量。 如果index超出范围,则返回原始列表。 |
3 | first(list) 返回列表中的第一个元素,如果list为空,则返回nil。 |
4 | flatten(list) 展平给定的嵌套列表列表。 |
5 | insert_at(list, index, value) 返回在指定索引处插入值的列表。 请注意,索引的上限为列表长度。 负指数表示从列表末尾的偏移量。 |
6 | last(list) 返回列表中的最后一个元素,如果list为空,则返回nil。 |
Tuples
元组也是在其中存储许多其他结构的数据结构。 与列表不同,它们将元素存储在连续的内存块中。 这意味着每个索引访问一个元组元素或获取元组大小是一个快速操作。 索引从零开始。
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_elem和insert_at返回了put_elem组。 存储在元组变量中的原始元组未被修改,因为Elixir数据类型是不可变的。 通过不可变,Elixir代码更容易推理,因为如果特定代码正在改变您的数据结构,您永远不必担心。
元组与列表
列表和元组之间有什么区别?
列表作为链表存储在内存中,这意味着列表中的每个元素都保持其值并指向以下元素,直到到达列表末尾。 我们将每对值和指针称为cons单元格。 这意味着访问列表的长度是一个线性操作:我们需要遍历整个列表以确定其大小。 只要我们预先添加元素,更新列表就很快。
另一方面,元组连续存储在存储器中。 这意味着获取元组大小或按索引访问元素很快。 但是,更新或向元组添加元素是昂贵的,因为它需要在内存中复制整个元组。