使用 returns 元组的函数更新地图列表
Update list of maps with function that returns tuple
我正在使用 Elixir 1.8.0 和 Ecto 3.0.7
我有一个看起来像这样的地图列表
things = [
%{
availability_zone: "us-west-1a",
dns_name: "ec2-13-45-67-46.us-west-1.compute.amazonaws.com",
image_id: "ami-251234",
instance_id: "i-1234",
instance_state: "running",
instance_type: "m4.large",
ip_address: "13.45.67.46",
key_name: "some_key",
launch_time: "2018-06-13T16:34:04.000Z",
monitoring: "disabled",
private_ip_address: "10.1.1.1",
vpc_id: "vpc-9999"
},
%{
availability_zone: "us-west-1a",
dns_name: "ec2-13-99-99-46.us-west-1.compute.amazonaws.com",
image_id: "ami-2522344",
instance_id: "i-99999",
instance_state: "running",
instance_type: "m4.large",
ip_address: "13.99.99.99",
key_name: "some_key",
launch_time: "2018-06-13T16:34:04.000Z",
monitoring: "disabled",
private_ip_address: "10.1.1.2",
vpc_id: "vpc-9999"
}
]
我正在尝试使用 Ecto.Repo.insert_all
将此列表插入到我的数据库中。这不起作用,因为我将 launch_time
称为 utc_datetime
而这不是我列表中的 DateTime。
我试图将它转换为 DateTime,但是,from_iso8601
returns 一个元组,当然,它不起作用。
iex(12)> things |> Enum.map(fn elem ->
...(12)> Map.update!(elem, :launch_time, &DateTime.from_iso8601/1)
...(12)> end)
[
%{
availability_zone: "us-west-1a",
dns_name: "ec2-13-56-179-46.us-west-1.compute.amazonaws.com",
image_id: "ami-25110f45",
instance_id: "i-0df401bc2d3b16d37",
instance_state: "running",
instance_type: "m4.large",
ip_address: "13.56.179.46",
key_name: "salt_provisioning",
launch_time: {:ok, #DateTime<2018-06-13 16:34:04.000Z>, 0},
monitoring: "disabled",
private_ip_address: "10.81.1.244",
vpc_id: "vpc-07a5e160"
},
%{
availability_zone: "us-west-1a",
dns_name: "ec2-13-56-179-46.us-west-1.compute.amazonaws.com",
image_id: "ami-25110f45",
instance_id: "i-0df401bc2d3b16d37",
instance_state: "running",
instance_type: "m4.large",
ip_address: "13.56.179.46",
key_name: "salt_provisioning",
launch_time: {:ok, #DateTime<2018-06-13 16:34:04.000Z>, 0},
monitoring: "disabled",
private_ip_address: "10.81.1.244",
vpc_id: "vpc-07a5e160"
}
]
我怎样才能只在我的管道中取回 DateTime,以便我可以 insert_all
我的列表?还是这需要多个步骤?
您现有的代码稍作改动即可使用,希望它符合您的要求:
things |> Enum.map(fn elem ->
{:ok, datetime, _} = DateTime.from_iso8601(elem[:launch_time])
Map.put(elem, :launch_time, datetime)
end)
虽然肯定可以 Enum.map/2
,但惯用且更灵活的方法是使用 Access
行为(Access.all/0
for lists,) and Kernel.get_and_update_in/3
:
get_and_update_in(things, [Access.all(), :launch_time], fn prev ->
{prev, with {:ok, neu, _} <- DateTime.from_iso8601(prev), do: neu}
end)
(或(prev |> DateTime.from_iso8601() |> elem(1))
)如果所有输入数据都被证明是有效的。
我正在使用 Elixir 1.8.0 和 Ecto 3.0.7
我有一个看起来像这样的地图列表
things = [
%{
availability_zone: "us-west-1a",
dns_name: "ec2-13-45-67-46.us-west-1.compute.amazonaws.com",
image_id: "ami-251234",
instance_id: "i-1234",
instance_state: "running",
instance_type: "m4.large",
ip_address: "13.45.67.46",
key_name: "some_key",
launch_time: "2018-06-13T16:34:04.000Z",
monitoring: "disabled",
private_ip_address: "10.1.1.1",
vpc_id: "vpc-9999"
},
%{
availability_zone: "us-west-1a",
dns_name: "ec2-13-99-99-46.us-west-1.compute.amazonaws.com",
image_id: "ami-2522344",
instance_id: "i-99999",
instance_state: "running",
instance_type: "m4.large",
ip_address: "13.99.99.99",
key_name: "some_key",
launch_time: "2018-06-13T16:34:04.000Z",
monitoring: "disabled",
private_ip_address: "10.1.1.2",
vpc_id: "vpc-9999"
}
]
我正在尝试使用 Ecto.Repo.insert_all
将此列表插入到我的数据库中。这不起作用,因为我将 launch_time
称为 utc_datetime
而这不是我列表中的 DateTime。
我试图将它转换为 DateTime,但是,from_iso8601
returns 一个元组,当然,它不起作用。
iex(12)> things |> Enum.map(fn elem ->
...(12)> Map.update!(elem, :launch_time, &DateTime.from_iso8601/1)
...(12)> end)
[
%{
availability_zone: "us-west-1a",
dns_name: "ec2-13-56-179-46.us-west-1.compute.amazonaws.com",
image_id: "ami-25110f45",
instance_id: "i-0df401bc2d3b16d37",
instance_state: "running",
instance_type: "m4.large",
ip_address: "13.56.179.46",
key_name: "salt_provisioning",
launch_time: {:ok, #DateTime<2018-06-13 16:34:04.000Z>, 0},
monitoring: "disabled",
private_ip_address: "10.81.1.244",
vpc_id: "vpc-07a5e160"
},
%{
availability_zone: "us-west-1a",
dns_name: "ec2-13-56-179-46.us-west-1.compute.amazonaws.com",
image_id: "ami-25110f45",
instance_id: "i-0df401bc2d3b16d37",
instance_state: "running",
instance_type: "m4.large",
ip_address: "13.56.179.46",
key_name: "salt_provisioning",
launch_time: {:ok, #DateTime<2018-06-13 16:34:04.000Z>, 0},
monitoring: "disabled",
private_ip_address: "10.81.1.244",
vpc_id: "vpc-07a5e160"
}
]
我怎样才能只在我的管道中取回 DateTime,以便我可以 insert_all
我的列表?还是这需要多个步骤?
您现有的代码稍作改动即可使用,希望它符合您的要求:
things |> Enum.map(fn elem ->
{:ok, datetime, _} = DateTime.from_iso8601(elem[:launch_time])
Map.put(elem, :launch_time, datetime)
end)
虽然肯定可以 Enum.map/2
,但惯用且更灵活的方法是使用 Access
行为(Access.all/0
for lists,) and Kernel.get_and_update_in/3
:
get_and_update_in(things, [Access.all(), :launch_time], fn prev ->
{prev, with {:ok, neu, _} <- DateTime.from_iso8601(prev), do: neu}
end)
(或(prev |> DateTime.from_iso8601() |> elem(1))
)如果所有输入数据都被证明是有效的。