Rails继续迭代后删除元素

时间:2015-08-10 16:09:07

标签: ruby-on-rails arrays loops

我有一个each循环,我想要在浏览过程中删除元素。像这样:

 @list.each do |elem|
      using = elem.get_similar_elems
      using.each do |u|
          //do stuff with 'using'
       end 
      @list = @list - using
  end

我原以为list - using部分会将其从整个.each循环中删除。

但相反,它继续循环遍历元素。我知道list - using是成功的,因为//do stuff部分没有做任何事情(即using中没有任何内容。)

我在想,each循环可能会在开头采用集合而list - using不会影响它。

所以我的2个问题是:

-1 - 这是正确的吗?

-2 - 我的目标如何实现?

3 个答案:

答案 0 :(得分:2)

首先list - using不会删除@list中的项目(我假设输入错误,但没有@)。它只是返回差异。 删除它们将是@list = @list - using。但这意味着在迭代过程中改变@list,行为将完全混乱。您应该将类​​似的项目存储在临时数组中,并在迭代完成后从列表中删除它们。

如果我理解您的意见,可能会有效的实施:

    used = []
    @list.each do |elem|    
      using = elem.get_similar_elems
      # discard elements used in previous iteration 
      # if you really want to do this, it's not clear
      using = using - used 
      # add new used elements
      used.concat using
      # do stuff with using

答案 1 :(得分:1)

在不知道@list中包含的内容的情况下,这样的内容可能有效:

@list.each do |elem|
   elem.get_similar_elems.each do |u|
      //do stuff with 'using'
   end 
   @list.delete(elem)
end

答案 2 :(得分:1)

你能在一开始就获得所有相似的元素吗?

@list.flat_map(&:get_similar_elems).uniq.each do |u|
end

编辑:我认为其他人提到的临时数组方法看起来像这样(你可以选择使用Set)

already_seen = []
@list.each do |elem|
  next if already_seen.include?(elem)
  using = elem.get_similar_elems
  using.each do |u|
  end
  already_seen += using
end