Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Elixir 基于map的cond和模式匹配_Elixir_Phoenix Framework - Fatal编程技术网

Elixir 基于map的cond和模式匹配

Elixir 基于map的cond和模式匹配,elixir,phoenix-framework,Elixir,Phoenix Framework,在phoenix应用程序中,当用户提交特定表单时,lat和lng根据地址计算 lat和lng可以在未进行更改的情况下保存在changeset.data中,也可以在提交更改的情况下保存在changeset.changes中 我在变更集中对lat和lng执行其他操作,但我需要知道坐标在哪里。我想做的是: cond do # Always use new coordinates if possible %{lat: lat, lng: lng} = changeset.changes -&g

在phoenix应用程序中,当用户提交特定表单时,lat和lng根据地址计算

lat和lng可以在未进行更改的情况下保存在changeset.data中,也可以在提交更改的情况下保存在changeset.changes中

我在变更集中对lat和lng执行其他操作,但我需要知道坐标在哪里。我想做的是:

cond do 
  # Always use new coordinates if possible
  %{lat: lat, lng: lng} = changeset.changes ->
    do_something(lat, lng)
  %{lat: lat, lng: lng} = changeset.data ->
    do_something(lat, lng)
  true ->
    do_nothing_and_return_the_changeset_as_is
end
当然,这不起作用,因为它不会在模式不匹配时返回
true
false

**(MatchError)右侧值不匹配:%{lat:any_value}

事实上,我做了一个很长的决定,看起来不太好,如果。。。。声明实现了这一点


有没有更好的长生不老药

您可以在以下函数中使用模式匹配:

...
# call do_something with the changeset
changset |> do_something()

#pattern match for lat,lng inside the changes
def do_something(%Ecto.Changeset{changes: {lat: lat, lng: lng}}) do
  ..
end

# pattern match for lat,lng inside data
def do_something(%Ecto_.Changeset{data: {lat: lat, lng: lng}}) do
  ..
end

# pattern match if no lat und lng are available !!! the order of the functions matters !!!
def do_something(%Ecto_Changeset{} = cs) do
  cs
end

代码未经测试,可能包括类型,但我希望您能理解。

您可以使用大小写匹配latlng内部更改数据

case changeset do
  %{changes: %{lat: lat, lng: lng}} -> ...
  %{data: %{lat: lat, lng: lng}} -> ...
  _ -> ...
end
但是,有一个更好的方法:Ecto有一个
get_field
函数,它处理从
更改中获取字段值,自动返回到
数据

lat = get_field(changeset, :lat)
lng = get_field(changeset, :lng)
if lat && lng do
  ...
else
  ...
end

在写下我的问题后,我发现这是我迄今为止没有测试过的选项。我现在正在尝试,我会回复你的!太好了,我没有意识到
get\u field
,这似乎也是一个很酷的选择!