我有两个数组输出,需要在每个结构上进行迭代,并比较源匹配的计数。比较必须小于或等于。我的输出源如下:
output_1: [%{source: "facebook", count: 3}, %{count: 1, source: "linkedin"}]
output_2: [%{source: "facebook", count: 2}, %{count: 1, source: "linkedin"}]
要使Enumerables最容易,最有效地进行比较,最好的数据结构是什么?
答案 0 :(得分:1)
如果不能保证您的订单,我的首选方法是将参考列表转换为地图并按来源进行比较。
iex> output_1 = [%{source: "facebook", count: 3}, %{count: 1, source: "linkedin"}]
[%{count: 3, source: "facebook"}, %{count: 1, source: "linkedin"}]
iex> output_2 = [%{source: "facebook", count: 2}, %{count: 1, source: "linkedin"}]
[%{count: 2, source: "facebook"}, %{count: 1, source: "linkedin"}]
iex> limits = Map.new(output_1, &{&1.source, &1.count})
%{"facebook" => 3, "linkedin" => 1}
iex> Enum.all?(output_2, & &1.count <= limits[&1.source])
true
答案 1 :(得分:1)
使用以下代码,您当前的输出格式应该非常有效。您没有说您期望的输出是什么,也没有说比较应该朝哪个方向进行:output2 <= output1
或output1 <= output2
,所以我假设是布尔值和output1 <= output2
的列表:
defmodule A do
def compare([%{count: count1}|maps1], [%{count: count2}|maps2]) do
[count1 <= count2 | compare(maps1, maps2) ]
end
def compare([], []), do: []
end
以下内容具有相同的作用,并且更容易理解和理解:
defmodule A do
def compare(list1, list2), do: _compare(list1, list2, [])
defp _compare([%{count: count1}|maps1], [%{count: count2}|maps2], acc) do
_compare(maps1, maps2, [count1 <= count2 | acc])
end
defp _compare([], [], acc) do
Enum.reverse(acc)
end
end
在iex中:
~/elixir_programs$ iex a.ex
Erlang/OTP 20 [erts-9.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]
Interactive Elixir (1.8.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> out1 = [%{source: "facebook", count: 3}, %{count: 1, source: "linkedin"}]
[
%{count: 3, source: "facebook"},
%{count: 1, source: "linkedin"}
]
iex(2)> out2 = [%{source: "facebook", count: 2}, %{count: 1, source: "linkedin"}]
[
%{count: 2, source: "facebook"},
%{count: 1, source: "linkedin"}
]
iex(3)> A.compare(out1, out2)
[false, true]
如果相反,您需要将结果设为单个布尔值,即Facebook计数小于或等于AND linkedin计数小于或等于,则可以更改累加器:
defmodule A do
def compare(list1, list2), do: _compare(list1, list2, true)
defp _compare([%{count: count1}|maps1], [%{count: count2}|maps2], true) do
_compare(maps1, maps2, count1 <= count2)
end
defp _compare(_, _, false), do: false #If you find a false comparison, stop and return false
defp _compare([], [], _), do: true
end
在iex中:
iex(22)> c "a.ex"
warning: redefining module A (current version defined in memory)
a.ex:1
[A]
iex(23)> A.compare(out1, out2)
false
这也有效:
defmodule A do
def compare(list1, list2) do
List.first(list1)[:count] <= List.first(list2)[:count]
and
List.last(list1)[:count] <= List.last(list2)[:count]
end
end
要使Enumerables最容易,最有效地进行比较,最好的数据结构是什么?
否则,我将这样提名keyword list:
[facebook: 3, linkedin: 1]
[facebook: 2, linkedin: 1]
答案 2 :(得分:0)
最简单的方法可能是将Enum.zip/2
与Enum.all?/2
一起使用。像下面这样的东西应该起作用
output_1 = Enum.sort(output_1, fn a, b -> a.source <= b.source end)
output_2 = Enum.sort(output_2, fn a, b -> a.source <= b.source end)
output_1
|> Enum.zip(output_2)
|> Enum.all?(fn a, b -> a.count == b.count end)