模拟用于'&'有重复

时间:2016-09-18 08:45:21

标签: ruby

来自Ruby文档:

  

ary& other_ary→new_ary

     

设置交叉点 -   返回一个包含两个数组共有元素的新数组,   不包括任何重复。订单保留原件   阵列。

但是否有内置方法来执行相同的操作包括重复

测试用例:

ary = [2, 7, 3, 7]
other_ary = [7, 2, 7, 4]
new_ary == [2, 7, 7]

3 个答案:

答案 0 :(得分:3)

下面的解决方案并不是最优雅的解决方案,但它在任何情况下都会返回正确答案:

[ary, other_ary].map { |e| e.group_by { |e| e } } # &:itself since 2.3
                .reduce { |memo, h| memo.merge(h) do |k, o, n|
                                      [o.count, n.count].min
                                    end } # merge to count
                .select { |_, v| Integer === v } # select only merged
                .flat_map { |k, v| [k] * v } # produce a result

或者,更优雅,变异的数组:

a1, a2 = [ary, other_ary].map(&:dup) # to keep originals intact
loop.inject([]) do |memo|
  break memo if a1.empty?
  memo << (a2.delete_at(a2.index a1.pop) rescue nil)
end.compact
#⇒ [7, 7, 2]

甚至:

a1, a2 = [ary, other_ary].map(&:dup) # to keep originals intact
loop.each_with_object([]) do |_, memo|
  break memo if a1.empty?
  a2.index(a1.pop).tap { |i| memo << a2.delete_at(i) if i }
end

答案 1 :(得分:2)

也许是这样的?

ary.select{ |a| other_ary.include? a }
#=> [2, 7, 7]

答案 2 :(得分:1)

我对该问题的理解是,您将获得两个数组ab,并希望返回包含n个每个元素e的{​​{1}}个副本的第三个数组在ab中,n = [a.count(e), a.count(e)].max

假设

a = [3,1,2,1,0,1]
b = [1,2,4,2,4,6]

我建议你执行以下三个步骤。

为每个数组构建一个计数哈希

ha = a.each_with_object(Hash.new(0)) { |n,h| h[n] += 1 }
  #=> {3=>1, 1=>3, 2=>1, 0=>1} 
hb = b.each_with_object(Hash.new(0)) { |n,h| h[n] += 1 }
  #=> {1=>1, 2=>2, 4=>2, 6=>1} 

确定两个阵列共有的元素

common_elements = a & b
  #=> [1, 2]

构建所需的数组

common_elements.flat_map { |n| [n]*[ha[n], hb[n]].max }
  #=> [1, 1, 1, 2, 2]