有条件地将数据插入数组中

时间:2014-09-16 16:55:53

标签: ruby arrays

好的,有人可以帮助我如何正确迭代动态大小的数组吗? 这就是我的意思:

my_array = [1, 2, 3, 4, 2, 5, 15, 2] # <= there are three 2 inside my_array 

然后我想添加&#34; good&#34;每当迭代达到整数2时,我尝试了几种方法,但没有找到方法,这是我尝试过的最好的方法(仍未达到我想要的效果)

# First Method
for i in 0..(my_array.length - 1)
 my_array.insert(i + 1, "good") if my_array[i] == 2
end

p my_array # => [1, 2, "good", 3, 4, 2, "good", 5, 15, 2] 

# Second Method
for i in 0..(my_array.length - 1)
 my_array[i + 1] = "good" if my_array[i] == 2
end

p my_array # => [1, 2, "good", 4, 2, "good", 15, 2, "good"] 

第一种方法并不好,因为它没有显示出好的&#34;在最后2之后,我想这是因为迭代无法到达最后一个整数2(在最后一个数组中)并且这是预期的,因为数组大小每次都变得更大&#34;好&#34;插入。

第二个也很糟糕,因为我每隔2个用'#34; good&#34;串。 现在有人可以向我指出我如何正确地做到这一点所以我可以像这样生产它:

 p my_array # => [1, 2, "good", 3, 4, 2, "good", 5, 15, 2, "good"]

所有&#34;好&#34;在不替换任何数据的情况下添加。

非常感谢任何帮助,非常感谢。

3 个答案:

答案 0 :(得分:3)

您可以更好地将其转换为新数组而不是就地修改:

my_array = [1, 2, 3, 4, 2, 5, 15, 2]

def add_good(a)
  a.flat_map do |value|
    case (value)
    when 2
      [ 2, 'good' ]
    else
      value
    end
  end
end

puts add_good(my_array).inspect
# => [1, 2, "good", 3, 4, 2, "good", 5, 15, 2, "good"]

flat_map方法对于您希望在结果数组中创建零个或多个条目的情况非常有用。 map是1:1映射,flat_map是1:N。

它也可以使这更通用:

def fancy_insert(a, insert)
  a.flat_map do |value|
    if (yield(value))
      [ value, insert ]
    else
      value
    end
  end
end

result = fancy_insert(my_array, 'good') do |value|
  value == 2
end

puts result.inspect

这样你就可以传入一个任意的块和值来插入。

答案 1 :(得分:2)

为什么不使用.each_with_index方法:

arr = [1, 2, 3, 4, 5, 2, 3, 5]
arr.each_with_index {|e, i| arr.insert(i+1, "good") if e == 2}

速度与激情。

答案 2 :(得分:0)

以下是另一种使用枚举器的方法:

my_array = [1, 2, 3, 4, 2, 5, 15, 2]

enum = my_array.each
  #=> #<Enumerator: [1, 2, 3, 4, 2, 5, 15, 2]:each>

my_array = []
loop do
  x = enum.next
  my_array << x
  my_array << "good" if x == 2
end
my_array
  #=> [1, 2, "good", 3, 4, 2, "good", 5, 15, 2, "good"]
当枚举数已经在最后一个元素上时,

Enumerator#next会引发StopInteration异常。 Kernel#loop通过打破循环来处理异常。这就是为什么在逐步通过枚举器时经常会看到loop的原因。