Как я могу повторить список в эликсире, чтобы создать другой список? - PullRequest
0 голосов
/ 10 марта 2020

У меня есть список кортежей в следующем формате

[{"string1",1},{"string2",2}...]

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

["string1", "string2",...]

Но я не уверен, как это сделать, поскольку я все еще изучаю, как работает Elixir. Мой способ получить это был так:

      for x <- words do
        text ++ elem(words,0)
      end

"text" - пустой список, а "words" - список кортежей. Но, конечно, это не работает, не совсем уверен, почему.

Ответы [ 2 ]

2 голосов
/ 10 марта 2020

Самый простой способ решить эту проблему - использовать Enum.map https://hexdocs.pm/elixir/Enum.html#map / 2

[{"string1", 1}, {"string2", 2}]
|> Enum.map(fn { string, _ } -> string)

Чтобы изучить Elixir, просто продолжайте делать то, что вы делаете, и посмотрите в Документы и спрашивайте здесь также

2 голосов
/ 10 марта 2020

Если вы хотите сделать это, используя 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 здесь может подойти вам лучше.

...