从 Ruby 字符串中按索引删除字符

4

给定一个包含字符串索引的序列,

str_indices = [[1,2],[7,8]],

如何最好地从字符串中排除这些字符?

例如,给定上述标记为排除的索引和字符串happydays,希望返回hpyda


1.8.7...感谢所有答案,我正在运行一些测试。 - mbm
最好使用范围数组来更本地化。[(1..2), (7..8), (10..20)] - fl00r
7个回答

6

使用范围:

str_indices=[[1,2],[7,8]]
str="happydays"
str_indices.reverse.each{|a| str[Range.new(*a)]=''}
str
=> "hpyda"

如果您不想修改原始内容:

str_indices.reverse.inject(str){|s,a|(c=s.dup)[Range.new(*a)]='';c}

你怎么知道他指的是范围?:) 我以为那只是一个奇怪的多维数组。 - fl00r
"包含的(inclusive)" Range 对我说。 - AShelly

2

猜测这是最好的做法。

str_indices = str_indices.flatten.reverse
string = "happydays"
str_indices.each{|i| string[i]=""}

除非你的索引是[[1,2],[6,8]],否则它会返回"hpyd"而不是"hpydy"。 - AShelly
@AShelly:是的,你说得对。我没有仔细阅读问题。为了修复它,在我展平数组时需要添加一个额外的步骤。 - Jatin Ganhotra

1

对于 Ruby 1.9,

string = 'happydays'
[-1, *str_indices.flatten(1), 0].each_slice(2).map{|i, j| string[i+1..j-1]}.join

对于 Ruby 1.8,请在此之前写入 require 'enumerator'


1
[[1,2],[7,8]].reverse.inject('happydays') { |m, (f,l)| m[f..l] = ''; m }

0

以下内容不要求str_indices所标识的范围是非重叠或以任何方式排序的。

str_indices = [[4,6], [1,2], [11,12], [9,11]]
str = "whatchamacallit"

keeper_indices = str.size.times.to_a -
                 str_indices.reduce([]) { |a,(from,to)| a | (from..to).to_a }
  # => [0, 3, 7, 8, 13, 14]

str.chars.values_at(*keeper_indices).join
  #=> "wtmait"

0

只是为了好玩 :)

str_indices = [[1,2],[7,8]]
str = "happydays"
str_indices.flatten.reverse.inject(str.split("")){|a,i| a.delete_at i; a}.join
#=> hpyda

0
如果您采用函数式编程方法,就不必担心索引的顺序。
str = "happydays"
indexes_to_reject = [[1,7],[2,8]] # Not in "correct" order, but still works
all_indexes = indexes_to_reject.flatten(1)
str.each_char.reject.with_index{|char, index| all_indexes.include?(index)}.join

它还可以与范围一起使用:

str = "happydays"
ranges_to_reject = [1..2, 7..8]
str.chars.reject.with_index {|char, index| 
  ranges_to_reject.any?{|range| range.include?(index)}
}.join

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