当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选项而不是组合几个迭代器吗?
答案 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*")