Elixir 将两个列表与地图进行比较
我有两张带地图的清单Elixir 将两个列表与地图进行比较,elixir,Elixir,我有两张带地图的清单 products= [ %{ "id" => "7", "use_count" => 1, "name" => "A", "price" => "$1", "base_count" => 2 }, %{ "id" => "8", "use_count" => 0, "name" => "B", "price" => "$14",
products= [
%{
"id" => "7",
"use_count" => 1,
"name" => "A",
"price" => "$1",
"base_count" => 2
},
%{
"id" => "8",
"use_count" => 0,
"name" => "B",
"price" => "$14",
"base_count" => 0
},
%{
"id" => "9",
"use_count" => 1,
"name" => "C",
"price" => "$29",
"base_count" => 0
}
]
及
我想根据id
比较2个列表。如果产品
中的任何基本计数
小于边距
的基本计数
,则我希望将错误作为
{:error, "product count cant be less than margin count"}
有人能帮忙吗
提前感谢。问题的形式非常不正确,在
产品中id
s是字符串,在边距中是整数,什么是“抛出错误”还不清楚
如前所述,可通过以下方式处理问题:
lookup=fn id->
(Enum.find(margin,&match?({id:^id},&1))| |%{base_count:0})。base_count
结束
结果=
reduce(乘积,%{},fn%{“id”=>id,“base\u count”=>base\u count},acc->
id=String.to_整数(id)
diff=查找(id)-基本计数
如果差异>0,
do:地图放置(acc、id、diff),
其他:行政协调会
(完)
现在可以检查result
是否为空,并“抛出”错误,不管它是什么意思
旁注:我会从规范化id
s开始,也许可以通过id
对页边距进行分组,以提高查找效率,但这将留给家庭作业。这是一个典型的问题,可以通过Elixir中的哈希表(或映射(数据类型)来解决
按id
检查是否存在base\u count
大于相应产品base\u count
的余量
正如Aleksei Matiushkin所说,数据类型的一致性非常重要。它可以帮助您编写更少的代码并避免许多bug。因此,如果可以,您确实应该首先修复数据。考虑产品和页边距ID是同一类型的
margin_base_count = Enum.into(margin, %{}, &{&1.id, &1.base_count})
Enum.reduce_while(products, :ok, fn %{"id" => id, "base_count" => base_count}, _acc ->
case base_count < margin_base_count[id] do
true -> {:halt, {:error, "product count cant be less than margin count"}}
false -> {:cont, :ok}
end
end)
margin\u base\u count=Enum.into(margin,%{},&{&1.id,&1.base\u count})
当(产品,:ok,fn%{“id”=>id,“base\u count”=>base\u count},\u acc->
案例基数计数<边际基数计数[id]do
true->{:halt,{:error,“产品计数不能小于边距计数”}
false->{:cont,:ok}
结束
(完)
Stream.map/2
在第一个代码片段中有一点意义(但它会减慢过程)。Enum.into(products,%{},&{String.to_integer(&1[“id”]),&1})
。但正如我在回答中所说的,我们必须开箱即用。@AlekseiMatiushkinEnum.group_by
给出的值是可能有点难以处理的列表。我希望长生不老药有一个Enum.index\u by/2
。
products_by_id = products
|> Stream.map(fn product -> {String.to_integer(product["id"]), product} end)
|> Enum.into(%{})
if Enum.any?(margin, fn m -> m[:base_count] > products_by_id[m[:id]]["base_count"] end) do
{:error, "product count cant be less than margin count"}
end
margin_base_count = Enum.into(margin, %{}, &{&1.id, &1.base_count})
Enum.reduce_while(products, :ok, fn %{"id" => id, "base_count" => base_count}, _acc ->
case base_count < margin_base_count[id] do
true -> {:halt, {:error, "product count cant be less than margin count"}}
false -> {:cont, :ok}
end
end)