我想按顺序获取包含列和值的列表,并将其转换为struct
。我目前在值上进行模式匹配,但随着列表的不断增长,我的代码变得越来越大。这是一些代码。
@find_account_query ~s{
SELECT
username, -- 1
name, -- 2
surname, -- 3
account.active, -- 4
CASE WHEN person_id IS NOT NULL
THEN TRUE
ELSE FALSE END AS isPerson -- 5
FROM account
LEFT JOIN person ON person.id = account.person_id
WHERE username = $1
}
def get(username), do:
conn
|> Connection.query(@find_account_query, [username])
|> parse_acct
defp parse_acct({:ok, %{ :num_rows => 0 }}), do: nil
defp parse_acct({:ok, %{ :columns => columns, :rows => [account]}}), do:
account |> parse_acct
##### The following function clause will get really long
defp parse_acct([username, name, surname, active, is_person]), do:
%Topaz.Account{
username: username,
name: name,
surname: surname,
active: active,
is_person: is_person
}
defp parse_acct(_), do: nil
如何简化从List
到struct
的过程?
答案 0 :(得分:0)
假设列列表和值列表对齐,您可以递归遍历列列表,并根据索引为结构赋值。
def get(username), do:
conn
|> Connection.query(@find_account_query, [username])
|> getp
defp parse_acct({:ok, %{ :num_rows => 0 }}), do: nil
defp parse_acct({:ok, %{ :columns => columns, :rows => [values]}}), do:
parse_acct(columns, values, %Topaz.Account{}, 0)
defp parse_acct([head|tail], values, account, index) do
# Get the corresponding atom in the model
atom = head |> String.to_atom
# Add the value to the account
account = account |> Map.put(atom, values |> Enum.at(index))
# Continue iterating
parse_acct(tail, values, account, index + 1)
end
# When iteration is done, return account
defp parse_acct([], values, account, index), do: account
答案 1 :(得分:0)
您可以使用结构只是一个带有defp parse_acct(values), do:
keys = [:username, :name, :surname, :active, :is_person]
keys
|> Enum.zip(values)
|> Enum.into(%{})
|> Map.merge(%Topaz.Account{})
end
键的地图来构建地图,然后添加相应的%Topaz.Account{} |> Map.keys |> Enum.filter(&(&1 != :__struct__))
键。像这样:
<script type="text/javascript">
$(document).ready(function () {
$.validator.setDefaults({
submitHandler: function (form) {
$.ajax({
type: "POST",
url: "contact_form.php",
data: $("#contactform").serialize()
}).done(function (data) {
alert(data);
swal("Mail Send!", "We will back to you soon", 'success');
$('#contactform').trigger("reset");
});
}
});
$("#contactform").validate({
rules:
{
name: {required: true, minlength: 3, maxlength: 50},
email: {required: true, email: true},
suburb: {required: true, minlength: 4},
phonenumber: {required: true, number: true, minlength: 4},
message: {required: false, maxlength: 300}
},
errorClass: "error",
highlight: function (label) {
$(label).closest('.form-group').removeClass('has-success').addClass('has-error');
},
success: function (label) {
label
// .text('Seems Perfect!').addClass('valid')
.closest('.form-group').addClass('has-success');
}
}
);
});
</script>
你可以进一步使用类似这样的东西从结构中提取键列表
<?php
print_r($_POST);
但是,这需要您的值始终按照Map枚举键的顺序传递(可能按字母顺序排列)