erlang 如何在Elixir中从ETS返回一个值?

mhd8tkvw  于 2022-12-08  发布在  Erlang
关注(0)|答案(1)|浏览(201)

i have ETS table that have key values scheme like this:

users = :ets.tab2list(:users)
IO.inspect users # printing

[
{"3eadd68495d",
%UserType{
 name: "John",
 id: "3eadd68495d",
 status: "Free"
}},
{"234a34495d",
%UserType{
 name: "Steve",
 id: "234a34495d",
 status: "Free"
}},
{"9add68495d",
%UserType{
 name: "Mike",
 id: "9add68495d",
 status: "Busy"
}}
]

And I want to get one id of any element, that have status "Free".
I'm already tried to get value using loop

users = :ets.tab2list(:users)
for user <- users do
   userValue = user |> elem(1)
   if userValue.status === "Free" do
     userValue.id
   end
end

but it returns multiple id values (3eadd68495d234a34495d), not one
i need smth like "break" after if userValue.status === "Free" do userValue.id but i have no idea how to use this in Elixir.

xkrw2x1b

xkrw2x1b1#

For the single value, one should use Enum.reduce_while/3.

Enum.reduce_while(users, nil, fn
  {_, %UserType{status: "Free", id: id}}, _ -> {:halt, id}
  _, acc -> {:cont, acc}
end)

or as pointed out by @sabiwara in comments, use Enum.find_value/2 .
I would not recommend this, but one might do try/catch to “break” the for comprehension as shown below.

try do
  for {_, %UserType{status: "Free", id: id}} <- users, do: throw(id)
catch
  id -> id
end

Somewhat alongside the following lines should do

:ets.select(
  :users,
  [{{:_, %{status: :"$1", id: :"$2"}},
   [{:"==", :"$1", "Free"}],
   [:"$2"]}])

相关问题