On using Enum.take_while/2

I am using Enum.take_while/2 to filter this list

[
  ["can't be blank"],
  ["can't be blank"],
  %{
    cost_price: ["can't be blank"],
    price: %{amount: ["can't be blank"]},
    sku: ["can't be blank"]
  },
  ["can't be blank"]
]|> Enum.take_while(fn  x-> is_map(x) end)

iex(6)> []

it returns empty list

but

[
  ["can't be blank"],
  ["can't be blank"],
  %{
    cost_price: ["can't be blank"],
    price: %{amount: ["can't be blank"]},
    sku: ["can't be blank"]
  },
  ["can't be blank"]
]|>Enum.map(fn x-> is_map(x) end)
iex()> [false, false, true, false]

I am failing to recognise the output of Enum.take_while/2
I need to take that map from the list
I am requesting for a help from the community
thanks and regards

https://hexdocs.pm/elixir/Enum.html#take_while/2

Takes the elements from the beginning of the enumerable while fun returns a truthy value.

The first element in the list returns a falsey value so no further elements are evaluated.

eg

iex(3)> Enum.take_while([1, 2, 3, 1], fn x -> x < 3 end)
[1, 2]

Were you looking for Enum.filter/2?

iex(5)> Enum.filter([1, 2, 3, 1], fn x -> x < 3 end)                   
[1, 2, 1]

?

2 Likes

This looks like you are trying to reinvent Changeset.traverse_errors/2?

1 Like

You can use Enum.filter/2

[
  ["can't be blank"],
  ["can't be blank"],
  %{
    cost_price: ["can't be blank"],
    price: %{amount: ["can't be blank"]},
    sku: ["can't be blank"]
  },
  ["can't be blank"]
]
|> Enum.filter(fn  x-> is_map(x) end)
1 Like

Not reinventing that list is the output of traverse_changeset/2

Ah. In that case go for Enum.filter as the others recommended:

Enum.filter(errors, &is_map/1)