使用keep_if的数组过滤器

时间:2013-08-08 10:26:59

标签: ruby

我有一个这样的数组:

array = ["john-56", "admin-57", "duke-58", "duke-65", 
         "john-56", "admin-57", "roger-65", "roger-15"]

我想只保留重复的元素,在这种情况下,我希望得到这个结果:

["admin-57","admin-57","john-56","john-56"]

我尝试过这样的keep_if方法:

array.keep_if { |x,y| x==y }

但它让array为空。

4 个答案:

答案 0 :(得分:3)

也许不是更高效,而是一行:

array.select { |x| array.count(x) == 2 }.uniq

@edit(感谢Jounty)

如果您的值超过两次

array.select { |x| array.count(x) > 1 }.uniq

答案 1 :(得分:3)

Array#keep_if仅传递迭代中的当前元素。

您可以使用:

duplicates = array.keep_if { |x| array.count(x) > 1 }.uniq

或者:

duplicates = array.uniq | array

答案 2 :(得分:1)

为了效率,首先计算它们,然后根据计算的计数

过滤它们
array = %w[ john-56 admin-57 duke-58  duke-65
            john-56 admin-57 roger-65 roger-15 ]

begin
  counts = {}
  array.each { |name| counts[name] = counts[name].to_i + 1 }
  array.keep_if { |name| counts[name] > 1 }
end

p array

<强>输出

["john-56", "admin-57", "john-56", "admin-57"]

或者,如果您不希望多次出现过滤后的元素,请写

begin
  counts = {}
  array.each { |name| counts[name] = counts[name].to_i + 1 }
  array = counts.select { |k, v| v > 1 }.keys
end

p array

<强>输出

["john-56", "admin-57"]

答案 3 :(得分:1)

array = %w[ 
  john-56   admin-57 
  duke-58   duke-65
  john-56   admin-57 
  roger-65  roger-15 
]

counts = Hash.new(0)
array.each {|name| counts[name] += 1}

results = []
counts.each do |key, count|
  results += [key]*count if count > 1
end

p results

--output:--
["john-56", "john-56", "admin-57", "admin-57"]