如何返回删除给定索引处字符的字符串?

3

我有一个字符串,例如:

string = 'foo-bar'

我需要一个不包含索引3处字符(在示例字符串中是-)的字符串,所以结果应该是 "foobar"。原始字符串不能改变。
以下是我目前的代码:
new_string = string.dup
new_string.slice!(3)
new_string
#=> "foobar"

string
#=> "foo-bar"

或者作为“一行代码”:
new_string = string.dup.tap { |s| s.slice!(3) }
#=> "foobar"

但是需要使用dup和可能的tap看起来很繁琐。有更简洁的方式吗?


我不知道这种方法是否已经存在,但是你总可以_创建_一个,并在其中隐藏dup/tap。 - Sergio Tulentsev
@SergioTulentsev 我认为我可能忽略了一个显而易见的解决方案。 - Stefan
肯定有这样的感觉,是的。 - Sergio Tulentsev
1
恰巧最近有一个功能请求,要求dup接受类似于tap的块。不确定这是否是一个好主意。 - cremno
FYI,我已经针对我认为是解决问题的可行方案打开了一个功能请求:https://bugs.ruby-lang.org/issues/14783 - Stefan
显示剩余2条评论
2个回答

2

我不知道有这样的方法。但你可以使用slice自己编写。

at = 3
string = "abc-def"
def delete_at(string, at)
  string.slice(0, at) + string.slice(at + 1, string.length)
end

x = delete_at(string, at) #> "abcdef"

你也可以对其进行猴子补丁,添加到 String 类中(虽然我不太喜欢这种方式)。

或者 string[0...at] + string[at + 1..-1] - Stefan
@Stefan 是的,那也可以。但我认为 [] 太过于多用了。所以我从不使用它。 https://ruby-doc.org/core-2.5.1/String.html#method-i-5B-5D - Pascal
2
String#[]String#slice 是别名。 - Stefan
@Stefan重载的意思是它被用于很多事情,例如访问数组/哈希的元素,而且我的大脑不太擅长解析String[] :-) - Pascal

1
似乎 `Kernel#sprintf` 可以相当简单地解决这个问题:
str = "foo-bar"
sprintf("%3.3s%s",str,str[4..-1])
#=> "foobar"

或者简单地

sprintf("%s%s",str[0..2],str[4..-1])
#=> "foobar"

此外,Enumerable 方法可能有所帮助,但似乎有点过度设计。
str.each_char.with_index.reduce("")  do |memo,(s,i)| 
  i == 3 ? memo : memo << s
end
#=> "foobar"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接