如果我有以下结构怎么办?
%Registration{email: "john@gmail.com", first_name: "John", last_name: "Doe"}
我想从中创建两个不同的结构:
%Account{email: "john@gmail.com", password: nil, ...}
%Profile{first_name: "John", last_name: "Doe", age: nil, ...}
我已经看了this question,但是如果我做了
registration = %Registration{email: "john@gmail.com", first_name: "John", last_name: "Doe"}
struct(Account, registration)
我收到protocol Enumerable not implemented for %Registration{...
所以我必须使用Map.from_struct
registration = %Registration{email: "john@gmail.com", first_name: "John", last_name: "Doe"}
struct(Account, Map.from_struct(registration))
但我觉得它不是很干净。所以我只是想有更好的方法来做到这一点吗?这应该是一个非常普遍的问题,对吧?
答案 0 :(得分:1)
根据文件:
将结构转换为地图。 它接受结构模块或结构本身并简单地删除 结构中的 struct 字段。
该功能存在是有原因的。我真的没有看到你做这件事的方式。如果这是一个常见的问题我以前还没有见过。如果您想要更具表现力或更清晰的代码,您可以尝试:
registration = %Registration{email: "john@gmail.com", first_name: "John", last_name: "Doe"} |> Map.from_struct
struct(Account, registration)
或其他等效代码,请查看文档here。
答案 1 :(得分:1)
你可以轻松地做到这一点,但有点笨拙 - 只需将协议功能委托给$('#btnSearch').click(function () {
console.clear();
$.ajax({
url: "/history/list",
data: {
startDate: $('#startDate').val(),
endDate: $('#endDate').val(),
},
type: "GET",
dataType: "html",
success: function (data) {
var result = $('<div />').append(data).find('#historyList').html();
$('#historyList').append(result);
console.log(result);
// the result is displayed correctly in the console...
},
error: function (xhr, status) {
alert("Sorry, there was a problem!");
},
complete: function (xhr, status) {
//$('#showresults').slideDown('slow')
}
});
});
:
Enumerable.Map
或以更合适的方式,如
defmodule Contact do
defstruct [:name, group: "", version: "", status: :latent]
defimpl Enumerable, for: Contact do
defdelegate([count(e), member?(e, m), reduce(e, a, f)],
to: Enumerable.Map)
end
end
可以使用宏生成
defmodule Contact do
defstruct [:name, group: "", version: "", status: :latent]
defimpl Enumerable do
alias Enumerable, as: E
def count(c), do: Map.from_struct(c) |> E.count()
def member?(c, m), do: Map.from_struct(c) |> E.member?(m)
def reduce(c, a, f), do: Map.from_struct(c) |> E.reduce(a, f)
end
end
实现,以返回编译时已知的struct members count。
Enumerable.count
也可以使用宏生成或手动编写或再次委派给Enumerable.member?
以消除Enumerable.Map.member?
的运行时惩罚。
上面的所有代码都是通用的,因此它可以放在Map.from_struct
- 像
use
并将其嵌入
defmodule StructEnumerable do
defmacro __using__(opts \\ []) do
quote do
defimpl Enumerable do
alias Enumerable, as: E
def count(c), do: Map.from_struct(c) |> E.count()
def member?(c, m), do: Map.from_struct(c) |> E.member?(m)
def reduce(c, a, f), do: Map.from_struct(c) |> E.reduce(a, f)
end
# you can also add following code
# to provide Fetch behaviour implementation
# for your structs
defdelegate([
fetch(t, k),
get_and_update(t, k, l)
], to: Map)
end
end
end