迭代时将项目插入数组

Insert items into an array while iterating

如何在遍历数组时修改(add/remove 个元素)并让迭代器知道它?

例如我认为这段代码:

a = "1234567890".split("")
a.each_with_index{|d, i|
 if d.eql?('5')
  a.delete_at(i)
  a.insert(i, ['A', 'B', 'C'] )
 end
print d
}

会产生:1234ABC67890 但会产生 1234567890

是否有变通方法或不同的方法来完成这项工作?

(我知道这个例子是非常简单的例子,但我正在做一些复杂的文本处理,当我点击一个关键字时我需要插入一些文本。我在进行扩展之前和之后做了很多功能所以在每个循环之外进行插入 [aka map!] 真的会使我的代码复杂化)

您通常不能在遍历其成员时修改 Enumerable。在大多数情况下,您需要随时构造一个新的 Enumerable。

b = []
a.each_with_index do |d, i|
  if d.eql?('5')
    b << 'A' << 'B' << 'C'
  else
    b << d
  end
end

实际上,您的代码有效,您只需将 print d 替换为 print a[i],因为您打印的是变量 d 而不是索引 [= 处的实际数组元素15=]

而不是删除和插入,为什么不更改该索引上的元素?

    a = "1234567890".split("")
    a.each_with_index{|d, i|
     if d.eql?('5')
      a[i] = ['A','B','C']
     end
    print a[i] #a[i] rather than d, since d contains the old value
    }

 ...
if d.eql?('5')
   a[i] = ['A','B','C']
   d = a[i]
end
print d

Deleting/Inserting 在迭代期间在数组上是不鼓励的,因为它可能会引起头痛哈哈......如果可能的话求助于其他方法:)

注意: 根据我的理解,我刚刚在您的代码中使用了当前逻辑,以及给定的期望输出

数组将变为 [1,2,3,4,['A','B','C'],6,7,8,9,0] 而不是[1,2,3,4,'A','B','C',6,7,8,9,0]。如果你想要另一个,请发表评论:)

如果您只想更改字符串中的值,您可以使用 .tr.gsub 来完成工作

这是一种选择。如果你想要 return 数组然后删除 join 否则将其保留为 return a String

a = "1234567890".split("")
a.collect! {|i| i == '5' ? ['A', 'B', 'C'] : i }.flatten!.join #=> "1234ABC67890"

最好避免在迭代时插入和删除。然而,当以相反顺序迭代时,一些问题消失了:

a = "1234567890".split("")
a.reverse_each.with_index{|d, i|
 if d.eql?('5')
  a.delete_at(i)
  a.insert(i, ['A', 'B', 'C'] )
 end
}
puts a.join # => 12345ABC7890