Ruby - 数组交集(有重复) [英] Ruby - array intersection (with duplicates)
问题描述
我有array(1 and 2)
.我怎样才能从他们那里得到 array3
?
I have array(1 and 2)
. How can I get array3
from them?
array1 = [2,2,2,2,3,3,4,5,6,7,8,9]
array2 = [2,2,2,3,4,4,4,4,8,8,0,0,0]
array3 = [2,2,2,3,4,8]
array1 &array2
返回 [2,3,4,8]
,但我需要保留重复项.
array1 & array2
returns [2,3,4,8]
, but I need to hold onto the duplicates.
推荐答案
(array1 & array2).flat_map { |n| [n]*[array1.count(n), array2.count(n)].min }
#=> [2,2,2,3,4,8]
步骤:
a = array1 & array2
#=> [2, 3, 4, 8]
a
(2
)的第一个元素被传递给block并赋值给block变量:
The first element of a
(2
) is passed to the block and assigned to the block variable:
n = 2
并执行块计算:
[2]*[array1.count(2), array2.count(2)].min
#=> [2]*[4,3].min
#=> [2]*3
#=> [2,2,2]
so 2
映射到 [2,2,2]
.a
的其余三个元素的计算类似.当我使用 flat_map
时,它返回 [2,2,2,3,4,8]
.
so 2
is mapped to [2,2,2]
. The calculations are similar for the remaining three elements of a
. As I am using flat_map
, this returns [2,2,2,3,4,8]
.
您是否难以记住 Enumerable#flat_map 与Enumerable#map?假设我使用了 map
而不是 flat_map
.那么
Do you have trouble remembering how Enumerable#flat_map differs from Enumerable#map? Suppose I had used map
rather than flat_map
. Then
a.map { |n| [n]*[array1.count(n), array2.count(n)].min }
#=> [[2, 2, 2], [3], [4], [8]]
flat_map
仅在每个数组前放置一个 splat 即可:
flat_map
does nothing more that put a splat in front of each of those arrays:
[*[2, 2, 2], *[3], *[4], *[8]]
#=> [2, 2, 2, 3, 4, 8]
如果数组 array1
和 array2
很大并且需要考虑效率,我们可以做一点 O(N) 预处理:
If the arrays array1
and array2
are large and efficiency is a concern, we could do a bit of O(N) pre-processing:
def cnt(arr)
arr.each_with_object(Hash.new(0)) { |e,h| h[e] += 1 }
end
cnt1 = cnt(array1)
#=> {2=>4, 3=>2, 4=>1, 5=>1, 6=>1, 7=>1, 8=>1, 9=>1}
cnt2 = cnt(array2)
#=> {2=>3, 3=>1, 4=>4, 8=>2, 0=>3}
(array1 & array2).flat_map { |n| [n]*[cnt1[n], cnt2[n]].min }
#=> [2,2,2,3,4,8]
这篇关于Ruby - 数组交集(有重复)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!