我有工作代码,但不喜欢它,它对我来说非常难看。我有两个不同的集合,我想删除一个集合中具有匹配键的元素。我已经“挑选”了用户从“选择”中选择的内容。所以我只想显示尚未挑选的“选择”。这是代码:
@picked.each do |p|
i = 0
@choices.each do |c|
if p.choices_id == c.id
@choices.delete_at(i)
break
end
i += 1
end
end
端
我特别不喜欢变量“i”。只是想到我会看到其他人可能会做些什么。
答案 0 :(得分:2)
改进代码
choices_ids = @picked.map(&:choices_id)
@choices.delete_if{ |c| choices_ids.include? c.id }
api:delete_if
<强> UPD 强>
您也可以随便简单地称之为:
@choices - @picked.map(&:choices).flatten
或
@choices -= @picked.map(&:choices).flatten
答案 1 :(得分:2)
@choices.reject! { |c| @picked.index { |p| p.choices_id == c.id } }
答案 2 :(得分:0)
Ruby支持集合的交集和差异:
picked = %w[1 2 3]
choices = %w[1 2 3 4 5]
choices - picked # => ["4", "5"]
编辑:
class Pick
attr_reader :choices_id
def initialize(id)
@choices_id = id
end
end
class Choice
attr_reader :id
def initialize(id)
@id = id
end
end
# cobble up some collections of objects
picked = %w[1 2 3].map{ |p| Pick.new(p) }
choices = %w[ 1 2 3 4 5].map{ |c| Choice.new(c) }
choices.map{ |c| c.id } - picked.map{ |p| p.choices_id } # => ["4", "5"]