返回ruby中字符串中出现的所有字符的索引
我试图使用Ruby将索引返回给字符串中所有出现的特定字符。示例字符串是返回ruby中字符串中出现的所有字符的索引,ruby,string,Ruby,String,我试图使用Ruby将索引返回给字符串中所有出现的特定字符。示例字符串是“A#asg#sdfg#d###”,搜索字符时,预期返回值是[1,5,10,12,13]。下面的代码可以完成这项工作,但是必须有一种更简单的方法来完成吗 def occurances (line) index = 0 all_index = [] line.each_byte do |x| if x == '#'[0] then all_index << index en
“A#asg#sdfg#d###”
,搜索
字符时,预期返回值是[1,5,10,12,13]
。下面的代码可以完成这项工作,但是必须有一种更简单的方法来完成吗
def occurances (line)
index = 0
all_index = []
line.each_byte do |x|
if x == '#'[0] then
all_index << index
end
index += 1
end
all_index
end
def发生(行)
索引=0
所有索引=[]
行。每个字节do | x|
如果x='#'[0],则
全部索引
ETA:这是通过创建一个枚举器来实现的,该枚举器使用scan(/#/)
作为其每个方法
扫描产生指定模式的每次出现(在本例中为/#/
),并且在块内,您可以调用Regexp.last_match来访问匹配的MatchData对象
MatchData#begin(0)
返回匹配开始的索引,由于我们在枚举器上使用了map,我们得到了这些索引的数组。这里有一个很长的方法链:
s = "a#asg#sdfg#d##"
a = (0 ... s.length).find_all { |i| s[i,1] == '#' }
"a#asg#sdfg#d##".
each_char.
each_with_index.
inject([]) do |indices, (char, idx)|
indices << idx if char == "#"
indices
end
# => [1, 5, 10, 12, 13]
“a#asg#sdfg#d#”。
每个字符。
每个_带有_索引。
注入([])do |索引(char,idx)|
指数[1,5,10,12,13]
需要1.8.7+以下是一种不那么花哨的方式:
i = -1
all = []
while i = x.index('#',i+1)
all << i
end
all
i=-1
全部=[]
当i=x.index(“#”,i+1)
所有根据FMc的答案得出的另一种解决方案:
s = "a#asg#sdfg#d##"
q = []
s.length.times {|i| q << i if s[i,1] == '#'}
s=“a#asg#sdfg#d#”
q=[]
s、 length.times{| i | q这是一个海量字符串的解决方案。我正在对4.5MB文本字符串进行文本查找,而其他解决方案则陷入停顿。这充分利用了ruby.split与字符串比较相比非常有效的事实
def indices_of_matches(str, target)
cuts = (str + (target.hash.to_s.gsub(target,''))).split(target)[0..-2]
indicies = []
loc = 0
cuts.each do |cut|
loc = loc + cut.size
indicies << loc
loc = loc + target.size
end
return indicies
end
在字符串末尾添加一些内容,以防目标位于末尾(以及拆分的工作方式),但还必须确保“随机”添加不包含目标本身
indices_of_matches("a#asg#sdfg#d##","#")
=> [1, 5, 10, 12, 13]
这些速度数字是从1.8.5开始的。在1.9.1中,这仍然是最快的,但find_all大约慢了3倍,enum_for大约慢了5倍!我快速猜测是Regexp.last_match.begin(0)
这会减慢enum_for
方法的速度。(也就是说,我希望enum_for
本身不是问题。)无论哪种方法,我都喜欢这既简单又可读。少花哨往往更好。这更快,因为在其他方法中,每个字符都会执行一个块。我在1.9中遇到并解决了一个类似的问题,你可以做。每个字符都有
(而不是每个字符。每个字符都有
)我认为那样读起来更好。s=“a#asg#sdfg#d####a=(0…s.length)。find|u all{I | s[I]=''.}应该工作得太好了吗?不需要,1…?@SamJoseph在这种情况下,是的,这两个是同义的。[x,y]
的2参数版本意味着“从code>开始的长度为y的子串”,与[x]
相同,意思是“x
处的字符(也是字符串,因为ruby没有字符类型)”。
(str + (target.hash.to_s.gsub(target,'')))
indices_of_matches("a#asg#sdfg#d##","#")
=> [1, 5, 10, 12, 13]