Enum find / filter from

I’m struggling a bit to filter items from a list.

I have this list with maps.

[%{behaviour: "top", id: 1}, 
%{behaviour: "sub", id: 2}, 
%{behaviour: "sub", id: 3}, 
%{behaviour: "top", id: 4}, 
%{behaviour: "sub", id: 5}, 
%{behaviour: "sub", id: 6}, 
%{behaviour: "top", id: 7},
%{behaviour: "sub", id: 8}]
...
...

what I need it to fetch all the maps with behaviour: “sub” from a specific id

For example;

form id: 4 I need the items with behaviour: “sub” until the next behaviour: “top” is reached.
so the result should be;

[%{behaviour: “sub”, id: 5},
%{behaviour: “sub”, id: 6}]

Can anyone point me in the right direction :slight_smile:

1 Like

Assuming the list is sorted, you may find the first “top” with the given id, and then just take all the next “subs”:

list
  |> Enum.split_while(list, fn x -> x != %{behaviour: "top", id: 4} end) 
  |> elem(1) 
  |> tl()
  |> Enum.take_while(fn x -> match?(%{behaviour: "sub"}, x) end)
2 Likes

Another way

iex(1)> [%{behaviour: "top", id: 1}, 
...(1)> %{behaviour: "sub", id: 2}, 
...(1)> %{behaviour: "sub", id: 3}, 
...(1)> %{behaviour: "top", id: 4}, 
...(1)> %{behaviour: "sub", id: 5}, 
...(1)> %{behaviour: "sub", id: 6}, 
...(1)> %{behaviour: "top", id: 7},
...(1)> %{behaviour: "sub", id: 8}] |>
...(1)> Stream.drop_while(fn(x) -> x.id != 4 end) |>
...(1)> Stream.drop(1) |>
...(1)> Enum.take_while(fn(x) -> x.behaviour != "top" end)
[%{behaviour: "sub", id: 5}, %{behaviour: "sub", id: 6}]
5 Likes

thanks :slight_smile: will try it tonight :sunny:

1 Like