我有2张地图。有什么方法可以找出一个Map
中存在哪些密钥,但另一个密钥中不存在这些密钥?
答案 0 :(得分:3)
将documentation与Map.keys/1
一起使用是最简单的方法:
# Suppose your two maps are:
map_a = %{a: 1, b: 2, c: 3, d: 4}
map_b = %{c: 3, d: 4, e: 5, f: 6}
# Get keys present in map_a but not in map_b
a_b_diff = Map.keys(map_a) -- Map.keys(map_b) # => [:a, :b]
# Get keys present in map_b but not in map_a
b_a_diff = Map.keys(map_b) -- Map.keys(map_a) # => [:e, :f]
答案 1 :(得分:3)
--
效率非常低。由于您已有地图,因此您可以使用O(log n)
在Map.has_key?/2
时间内查找是否存在任何密钥。可以使用带过滤器的简单for
来获得所需的结果:
iex(1)> map1 = %{a: 1, b: 2, d: 3, f: 4}
%{a: 1, b: 2, d: 3, f: 4}
iex(2)> map2 = %{b: 5, c: 6, f: 7, g: 8}
%{b: 5, c: 6, f: 7, g: 8}
iex(3)> for {k, _} <- map1, !Map.has_key?(map2, k), do: k
[:a, :d]
使用大型地图的快速基准测试显示与Kernel.--/2
的巨大性能差异:
map1 = for x <- Enum.take_random(1..10000, 5000), into: %{}, do: {x, x}
map2 = for x <- Enum.take_random(1..10000, 5000), into: %{}, do: {x, x}
{time, result1} = :timer.tc(fn ->
Map.keys(map1) -- Map.keys(map2)
end)
IO.puts "--: #{time}µs"
{time, result2} = :timer.tc(fn ->
for {k, _} <- map1, !Map.has_key?(map2, k), do: k
end)
IO.puts "for: #{time}µs"
IO.inspect result1 == result2
输出:
--: 113367µs
for: 739µs
true
如果您的地图很小,--
肯定会比这更短,更可读,并且应该足够好。