一次在字符串中插入多个字符

时间:2018-06-07 18:41:25

标签: ruby

当str []替换字符时,str.insert会在某个位置插入一个字符。但它需要两行代码:

str = "COSO17123456"
str.insert 4, "-"
str.insert 7, "-"
=> "COSO-17-123456"

我正在考虑如何在一行代码中执行此操作。我提出了以下解决方案:

str =  "COSO17123456"
str.each_char.with_index.reduce("") { |acc,(c,i)| acc += c + ( (i == 3 || i == 5) ? "-" : "" ) }
  => "COSO-17-123456 

是否有针对此任务的内置Ruby助手?如果没有,我应该坚持使用insert选项而不是组合几个迭代器吗?

3 个答案:

答案 0 :(得分:3)

使用each迭代一系列索引:

str = "COSO17123456"
[4, 7].each { |i| str.insert i, '-' }
str #=> "COSO-17-123456"

答案 1 :(得分:1)

您可以使用切片和.join

> [str[0..3], str[4..5],str[6..-1]].join("-")
=> "COSO-17-123456"

请注意,第一个(3到4之间)之后的索引会有所不同,因为您没有先插入先前的插入。即,更自然(无论如何......)

您将插入原始字符串的绝对索引 - 而不是插入时的移动相对索引。

如果要插入特定的绝对索引值,还可以使用..each_with_index并按字符控制行为字符:

str2 = ""
tgts=[3,5]
str.split("").each_with_index { |c,idx| str2+=c; str2+='-' if tgts.include? idx }

以上两者都创建了一个新字符串。

答案 2 :(得分:0)

String#insert返回字符串本身。

这意味着你可以链接方法调用,如果你只需像你的例子那样做几次就可以更漂亮,更高效:

str = "COSO17123456".insert(4, "-").insert(7, "-")
puts str
COSO-17-123456

因此,您的reduce版本可以更简洁地写为:

[4,7].reduce(str) { |str, idx| str.insert(idx, '-') }

我会再向表中添加一个变体String#unpack

new_str = str.unpack("A4A2A*").join('-')
# or with String#%
new_str = "%s-%s-%s" % str.unpack("A4A2A*")