映射数组而不丢失未更改的元素

时间:2016-03-10 17:56:59

标签: arrays ruby

我拆分了以下字符串:

str = "0001110010101000011111100001110010000010000000011101011100001"

分组为"0""1" s:

str_arr = []
str.scan(/((.)\2*)/) { |x| str_arr.push(x[0]) }

str_arr # => ["000", "111", "00", "1", "0", "1", "0", "1", "0000", "111111", "0000", "111", "00", "1", "00000", "1", "00000000", "111", "0", "1", "0", "111", "0000", "1"]

我想要替换包含字符"1"并且length少于3个字符的字符"."的元素,但保留其他元素。

我在我的代码中达到了这个目标:

str_arr.map!{|x| if x.include?("1") && x.length < 3; x = "." end}

str_arr # => [nil, nil, nil, ".", nil, ".", nil, ".", nil, nil, nil, nil, nil, ".", nil, ".", nil, nil, nil, ".", nil, nil, nil, "."]

最后一步是我绊倒的地方。我将我想要的元素转换为".",但将剩余的元素转换为nil

有没有办法在不影响剩余元素的情况下替换我想要更改的元素?

2 个答案:

答案 0 :(得分:4)

它们被转换的原因是因为如果条件不满足,ruby中的if语句将返回nil

if false; end # => nil

要解决此问题,只需使用三元运算符(?:)代替if then end并提供原始值作为替代:

str_arr.map!{ |x| x.include?('1') && x.length < 3 ? '.' : x }

<强>加成

一个更简单的正则表达式,它也会这样做:

0+|1+

答案 1 :(得分:2)

在这种情况下,使用each_index是合适的。

str_arr.each_index{|i| str_arr[i] = "." if str_arr[i] =~ /\A1{,2}\z/}
# => ["000", "111", "00", ".", "0", ".", "0", ".", "0000", "111111", "0000", "111",
#    "00", ".", "00000", ".", "00000000", "111", "0", ".", "0", "111", "0000", "."]