Bitwise
Bitwise

Reputation: 8461

Check if list element is within another list - Elixir

If I have two lists:

First list => [1,2,3]
Second List => [3,4,5]

I want this to return true because they both contain 3? If 3 was replaced by 6 it would return false because no elements would match.

Current Attempt

Enum.member?(first_list, fn(x) -> x == second_list end)

Ecto queries:

user_teams = from(
  t in MyApp.Team,
  left_join: a in assoc(t, :accounts),
  where: p.owner_id == ^user.id or (a.user_id == ^user.id and t.id == a.project_id)
) |> Repo.all

current_user_teams = from(
  t in MyApp.Team,
  left_join: a in assoc(t, :accounts),
  where: t.owner_id == ^current_user.id or (a.user_id == ^current_user.id and p.id == a.project_id)
) |> Repo.all

Current Fix:

Enum.any?(user_projects, fn(p) -> p in current_user_projects end)

Upvotes: 5

Views: 4498

Answers (3)

Hauleth
Hauleth

Reputation: 23556

If lists are large then you can use MapSet to check if these lists are disjoint:

iex(1)> xs = [1, 2, 3]
[1, 2, 3]
iex(2)> ys = [3, 4, 5]
[3, 4, 5]
iex(3)> not MapSet.disjoint?(MapSet.new(xs), MapSet.new(ys))
true

And if you want to know what is the intersection (elements that are common in both sets) then you can use:

iex(1)> xs = [1, 2, 3]
[1, 2, 3]
iex(2)> ys = [3, 4, 5]
[3, 4, 5]
iex(3)> MapSet.intersect(MapSet.new(xs), MapSet.new(ys))
#MapSet<[3]>

Upvotes: 7

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121000

You might get in intersection in the first place, and then validate whether it’s empty or not:

case for i <- [1,2,3], i in [3,4,5], do: i do
  [] -> false
  [_|_] -> true
end

Upvotes: 2

Dogbert
Dogbert

Reputation: 222118

Use Enum.any?/2 with the in operator (which is just a shorter form of calling Enum.member?/2):

iex(1)> xs = [1, 2, 3]
[1, 2, 3]
iex(2)> ys = [3, 4, 5]
[3, 4, 5]
iex(3)> Enum.any?(xs, fn x -> x in ys end)
true

Upvotes: 11

Related Questions