Elixir最佳数据结构以进行测试比较

时间:2019-06-17 14:04:28

标签: testing elixir

我有两个数组输出,需要在每个结构上进行迭代,并比较源匹配的计数。比较必须小于或等于。我的输出源如下:

output_1: [%{source: "facebook", count: 3}, %{count: 1, source: "linkedin"}]

output_2: [%{source: "facebook", count: 2}, %{count: 1, source: "linkedin"}]

要使Enumerables最容易,最有效地进行比较,最好的数据结构是什么?

3 个答案:

答案 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 <= output1output1 <= 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/2Enum.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)