Если вы хотите сделать это, используя for
, вы должны понимать, что for
- это не конструкция для перебора объектов, как в других языках программирования. В Elixir for
используется для понимания, что означает, что результатом будет структура данных, созданная из перечислимого типа вашего списка кортежей.
Вам также нужно понимать, что если вы обновили свой код, text ++ elem(words, 0)
на самом деле не будет обновлять text
, и это ++
тоже не работает так, как вы думаете. ++
полезно для объединения списков или списков ключевых слов, но не для добавления отдельных элементов в список. Для этого вы можете сделать list ++ ["string"]
или ["string"] ++ list
, что быстрее; или даже проще: ["string" | list]
.
И причина, по которой он не будет обновлять ваш список, состоит в том, что на каждой «итерации» вы просто производите конкатенацию, но на самом деле вы нигде не будете ее назначать , И вещи в Elixir не являются изменяемыми, поэтому ++
фактически не обновляет что-либо
Теперь, чтобы правильно создать то, что вы хотите, используя for
, вы можете сделать это следующим образом:
iex> list = [{"string1", 1}, {"string2", 2}]
[{"string1", 1}, {"string2", 2}]
iex> for tup <- list, do: elem(tup, 0)
["string1", "string2"]
iex> for {string, _} <- list, do: string
["string1", "string2"]
Что в основном означает: используя этот список, создайте новый, сохранив только первый элемент каждого кортежа. Поскольку список является выводом по умолчанию for
. Но вы также можете изменить результирующую структуру данных, добавив into: %{}
или что-то еще. Понятия очень мощные, вы можете лучше понять их здесь
Еще один популярный способ решить эту проблему - использовать Enum.map
, который отображает заданное перечисляемое в другое. Это означает, что он преобразует элементы перечислимого, поэтому вы можете сделать это также следующим образом:
iex> list = [{"string1", 1}, {"string2", 2}]
[{"string1", 1}, {"string2", 2}]
iex> Enum.map(list, fn {string, _} -> string end)
["string1", "string2"]
Здесь преобразование будет выполнено функцией, которая принимает кортеж, сопоставляя первый элемент во что-то Вызывается string
и «возвращает» только это для каждого элемента.
Еще один простой способ сделать это - использовать Enum.unzip/1
, который принимает список двухэлементных кортежей, таких как у вас, и производит кортеж с двумя элементами. Первый представляет собой список с первым элементом из каждого из ваших кортежей, а второй - список со вторым элементом из каждого из ваших кортежей.
Итак, вы можете сделать:
iex> list = [{"string1",1},{"string2",2}]
[{"string1", 1}, {"string2", 2}]
iex> {strings, _} = Enum.unzip(list)
{["string1", "string2"], [1, 2]}
iex> strings
["string1", "string2"]
Таким образом, вы останетесь со строковой переменной, содержащей список, который вы хотите. Однако это работает только с кортежами из двух элементов, поэтому, если у вас есть кортеж с более чем двумя, он не будет работать. Кроме того, вы не будете использовать второй список, поэтому понимание for
здесь может подойти вам лучше.