用于测试比较的Elixir最佳数据结构



我有两个数组输出,我需要在其中迭代每个结构,并比较源匹配的计数。比较需要小于或等于。我的输出源如下所示:

output_1: [%{source: "facebook", count: 3}, %{count: 1, source: "linkedin"}]
output_2: [%{source: "facebook", count: 2}, %{count: 1, source: "linkedin"}]
为了使枚举最

容易和最有效的比较,要实现的最佳数据结构是什么?

如果您的订单无法保证,我的首选方法是将参考列表转换为地图并按来源进行比较。

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

使用以下代码,您当前的输出格式应该非常有效。 你没有说你期望你的输出是什么,也没有说应该在哪个方向进行比较: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
为了使枚举最

容易和最有效的比较,要实现的最佳数据结构是什么?

否则,我会提名一个这样的关键字列表:

[facebook: 3, linkedin: 1]
[facebook: 2, linkedin: 1]

最简单的可能是将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)

最新更新