Список не является массивом

Когда я впервые увидел приведенный ниже код, я подумал, что это, вероятно, массив. А потом, возможно, и у вас возникла такая же мысль. lol

# Creating a list
list = [1, :atom, 3, 4, "string"]
Вход в полноэкранный режим Выйти из полноэкранного режима

Но в Elixir код выше — это List.

Что такое список?

В нескольких словах, список — это связанный список. Но чтобы лучше понять, давайте вспомним, что такое массив, а затем поговорим о списке.

О массиве

Массив — это коллекция данных одного типа.

В массиве мы можем получить доступ к содержимому через индексы. И когда нам нужно, например, получить третий элемент массива напрямую, в Ruby мы можем сделать это, передав индекс номер 2:

> x = [1, 2, 3, 4]
[1, 2, 3, 4]

> x[2]
3
Вход в полноэкранный режим Выйти из полноэкранного режима

Другая особенность массива заключается в том, что мы можем выполнять итерации между элементами, один за другим, напрямую. В Ruby мы можем сделать это следующим образом:

> x.each{|element| puts element}
1
2
3
4
Войти в полноэкранный режим Выйти из полноэкранного режима

Теперь давайте снова вернемся к разговору о List и Elixir.

В Elixir списки являются связанными списками. Это означает, что каждый элемент связан со следующим элементом через позицию в памяти.

Как мы можем перебирать элементы в списке?

Прежде всего, нам нужно знать, что список состоит из двух частей: голова — это первый элемент списка, а хвост — остальные элементы.

В Elixir у нас есть функция ядра hd(list) для доступа к первому элементу списка (head), а также функция ядра tl(list) для доступа к остальным элементам списка (tail). Посмотрите на пример ниже:

> # creating the List
> list = [1, :atom, 3, 4, "string"]
[1, :atom, 3, 4, "string"]

> # Return the first item of the List - Head
> hd(list)
1

> # Return the rest of items of the List - Tail
> tl(list)
[:atom, 3, 4, "string"]
Вход в полноэкранный режим Выход из полноэкранного режима

Также можно получить доступ к head и tail списка, используя Pattern Matching:

# Creating a list
> list = [1, :atom, 3, 4, "string"]
[1, :atom, 3, 4, "string"]

# Using Pattern Matching to assign the first element 
# to the head and the rest of the list to the tail.
> [head | tail] = list
[1, :atom, 3, 4, "string"]

# Return the first element from the list
> head
1

# Return the rest of elements from the list
> tail
[:atom, 3, 4, "string"]
Войти в полноэкранный режим Выйти из полноэкранного режима

А для итерации каждого элемента списка мы используем рекурсию:

# Creating the module as example
defmodule Example do
  def show_each_one([head | tail]) do
    # The kernel function IO to show the content of head
    IO.puts(head)

    # Calling the function itself
    # (where the recursion happens)
    # by passing the tail as the argument of the function
    show_each_one(tail)
  end

  # Creating the function using the pattern Matching
  # In the case of an empty list, it will return null (nil)
  def show_each_one([]), do: nil
end

# Creating a list
list = [1, :atom, 3, 4, "string"]
[1, :atom, 3, 4, "string"]


# Call the function Example.show_each_one/1
# by passing the list as argument
Example.show_each_one(list)

# It will return the result below:
1
atom
3
4
string
nil
Войти в полноэкранный режим Выйти из полноэкранного режима

Мы могли бы использовать множество других функций ядра для работы со списками:

  • И многие другие.

Если вам нужно узнать больше о деталях работы со списком, я советую вам посмотреть документацию по списку в Elixir.

Кое-что интересное, что нам нужно знать, это то, что функции, которые мы используем для работы со списком, используют рекурсию в своей реализации.

Я надеюсь, что этот материал поможет вам и будет иметь смысл! До встречи!

Контакты:
Email: contato@diegonovais.com.br
LinkedIn: https://www.linkedin.com/in/diegonovais/
Github: https://github.com/dnovais
Twitter: https://twitter.com/diegonovaistech

Оцените статью
devanswers.ru
Добавить комментарий