我想根据重复次数(> = 3)拒绝哈希数组中的重复。
例如:重复的标准只是名称,而与数字无关。
.woocommerce ul.products li.product a img
{
height: 400px !important;
}
我要拒绝重复两次以上的“名称”。 该函数应返回:
a = [{:name=>"John Doe1", :number=>"5551234567"},
{:name=>"John Doe1", :number=>"5551234567"},
{:name=>"John Doe2", :number=>"5557654321"},
{:name=>"John Doe1", :number=>"5551234567"}]
我在下面尝试了这可能是错误的:
[{:name=>"John Doe2", :number=>"5557654321"}]
答案 0 :(得分:3)
Enumerable#reject
和Enumerable#count
可能有帮助:
arr = [
{:name=>"John Doe1", :number=>"5551234567"},
{:name=>"John Doe1", :number=>"5551234567"},
{:name=>"John Doe2", :number=>"5557654321"},
{:name=>"John Doe1", :number=>"5551234567"}
]
p arr.reject { |hsh| arr.count(hsh) > 2 }
# => [{:name=>"John Doe2", :number=>"5557654321"}]
根据评论,添加用法Enumerable#map
:
names = arr.map { |hsh| hsh[:name] }
p arr.reject { |hsh| names.count(hsh[:name]) > 2 }
答案 1 :(得分:1)
这是O(n),在更大的列表上可能会做得更好:
a.group_by { |el| el[:name] }.reject { |_, v| v.size > 2 }.values.flatten
答案 2 :(得分:1)
假设我们给出以下数组(与问题中给出的数组不同)。
arr = [{ :name=>"John Doe1", :number=>"5551234567" },
{ :name=>"John Doe3", :number=>"5551234567" },
{ :name=>"John Doe1", :number=>"5551234567" },
{ :name=>"John Doe2", :number=>"5557654321" },
{ :name=>"John Doe3", :number=>"5551234567" },
{ :name=>"John Doe1", :number=>"5551234567" }]
我们可以如下获得所需的值。
arr.values_at(*arr.each_with_index.with_object({}) { |(g,i),h| (h[g] ||= []) << i }.
values.
select { |a| a.size < 3 }.
flatten.
sort)
#=> [{:name=>"John Doe3", :number=>"5551234567"},
# {:name=>"John Doe2", :number=>"5557654321"},
# {:name=>"John Doe3", :number=>"5551234567"}]
步骤如下。
enum0 = arr.each_with_index
#=> #<Enumerator: [{:name=>"John Doe1", :number=>"5551234567"},
# {:name=>"John Doe3", :number=>"5551234567"},
# ...
# {:name=>"John Doe1", :number=>"5551234567"}]:each_with_index>
enum1 = enum0.with_object({})
#=> #<Enumerator:
# #<Enumerator: [{:name=>"John Doe1", :number=>"5551234567"},
# {:name=>"John Doe3", :number=>"5551234567"},
# ...
# {:name=>"John Doe1", :number=>"5551234567"}]:each_with_index>
# :with_object({})>
b = enum1.each { |(g,i),h| (h[g] ||= []) << i }
#=> {{:name=>"John Doe1", :number=>"5551234567"}=>[0, 2, 5],
# {:name=>"John Doe3", :number=>"5551234567"}=>[1, 4],
# {:name=>"John Doe2", :number=>"5557654321"}=>[3]}
c = b.values
#=> [[0, 2, 5], [1, 4], [3]]
d = c.select { |a| a.size < 3 }
#=> [[1, 4], [3]]
f = e.sort
#=> [1, 3, 4]
arr.values_at(*f)
#=> [{:name=>"John Doe3", :number=>"5551234567"},
# {:name=>"John Doe2", :number=>"5557654321"},
# {:name=>"John Doe3", :number=>"5551234567"}]
答案 3 :(得分:0)
整个答案已根据@CarySwoveland的启发进行了重新编写(对于以前的实现,请随时查看所做的编辑)。
这2个选项似乎是处理这种情况的最有效方法
a.group_by { |el| el[:name] }.each_with_object([]) do |(_, v),obj|
obj.concat(v) if v.size < 3
end
#or
a.group_by { |el| el[:name] }.flat_map { |_, v| v if v.size < 3 }.compact