ruby delete_at调高

时间:2011-04-22 19:30:09

标签: ruby

我有工作代码,但不喜欢它,它对我来说非常难看。我有两个不同的集合,我想删除一个集合中具有匹配键的元素。我已经“挑选”了用户从“选择”中选择的内容。所以我只想显示尚未挑选的“选择”。这是代码:

@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”。只是想到我会看到其他人可能会做些什么。

3 个答案:

答案 0 :(得分:2)

Ruby 1.9 +

each_with_indexwith_index

改进代码

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"]