Ruby String
类中是否有任何内置函数可以为我提供Ruby中字符串的所有前缀。类似的东西:
"ruby".all_prefixes => ["ruby", "rub", "ru", "r"]
目前我已为此制作了自定义功能:
def all_prefixes search_string
dup_string = search_string.dup
return_list = []
while(dup_string.length != 0)
return_list << dup_string.dup
dup_string.chop!
end
return_list
end
但我正在寻找更多的rubylike,更少的代码和神奇的东西。
注意:当然不用说original_string
应保持不变。
答案 0 :(得分:9)
不,没有内置的方法。你可以这样做:
def all_prefixes(string)
string.size.times.collect { |i| string[0..i] }
end
all_prefixes('ruby')
# => ["r", "ru", "rub", "ruby"]
答案 1 :(得分:7)
快速基准:
require 'fruity'
string = 'ruby'
compare do
toro2k do
string.size.times.collect { |i| string[0..i] }
end
marek_lipka do
(0...(string.length)).map{ |i| string[0..i] }
end
jorg_w_mittag do
string.chars.inject([[], '']) { |(res, memo), c|
[res << memo += c, memo]
}.first
end
jorg_w_mittag_2 do
acc = ''
string.chars.map {|c| acc += c }
end
stefan do
Array.new(string.size) { |i| string[0..i] }
end
end
获胜者是:
Running each test 512 times. Test will take about 1 second.
jorg_w_mittag_2 is faster than stefan by 19.999999999999996% ± 10.0%
stefan is faster than marek_lipka by 10.000000000000009% ± 10.0%
marek_lipka is faster than jorg_w_mittag by 10.000000000000009% ± 1.0%
jorg_w_mittag is similar to toro2k
答案 2 :(得分:6)
def all_prefixes(str)
acc = ''
str.chars.map {|c| acc += c }
end
答案 3 :(得分:5)
怎么样?
str = "ruby"
prefixes = Array.new(str.size) { |i| str[0..i] } #=> ["r", "ru", "rub", "ruby"]
答案 4 :(得分:4)
这可能是一个很长的镜头,但是如果你想为一组字符串找到不同的缩写,你可以使用Abbrev
模块:
require 'abbrev'
Abbrev.abbrev(['ruby']).keys
=> ["rub", "ru", "r", "ruby"]
答案 5 :(得分:3)
稍微缩短形式:
def all_prefixes(search_string)
(0...(search_string.length)).map{ |i| search_string[0..i] }
end
all_prefixes 'ruby'
# => ["r", "ru", "rub", "ruby"]
答案 6 :(得分:1)
def all_prefixes(str)
str.chars.inject([[], '']) {|(res, memo), c| [res << memo += c, memo] }.first
end
答案 7 :(得分:1)
str = "ruby"
prefixes = str.size.times.map { |i| str[0..i] } #=> ["r", "ru", "rub", "ruby"]
答案 8 :(得分:0)
之前没有提到的两个,比@ toro2k接受的比较answer更快。
(1..s.size).map { |i| s[0, i] }
=> ["r", "ru", "rub", "ruby"]
Array.new(s.size) { |i| s[0, i+1] }
=> ["r", "ru", "rub", "ruby"]
奇怪的是,之前没有人使用过String#[start, length]
,只有较慢的String#[range]
我认为至少我的第一个解决方案非常简单。
基准测试结果(使用Ruby 2.4.2):
user system total real
toro2k 14.594000 0.000000 14.594000 ( 14.724630)
marek_lipka 12.485000 0.000000 12.485000 ( 12.635404)
jorg_w_mittag 16.968000 0.000000 16.968000 ( 17.080315)
jorg_w_mittag_2 11.828000 0.000000 11.828000 ( 11.935078)
stefan 10.766000 0.000000 10.766000 ( 10.831517)
stefanpochmann 9.734000 0.000000 9.734000 ( 9.765227)
stefanpochmann 2 8.219000 0.000000 8.219000 ( 8.240854)
我的基准代码:
require 'benchmark'
string = 'ruby'
@n = 10**7
Benchmark.bm(20) do |x|
@x = x
def report(name, &block)
@x.report(name) {
@n.times(&block)
}
end
report('toro2k') {
string.size.times.collect { |i| string[0..i] }
}
report('marek_lipka') {
(0...(string.length)).map{ |i| string[0..i] }
}
report('jorg_w_mittag') {
string.chars.inject([[], '']) { |(res, memo), c|
[res << memo += c, memo]
}.first
}
report('jorg_w_mittag_2') {
acc = ''
string.chars.map {|c| acc += c }
}
report('stefan') {
Array.new(string.size) { |i| string[0..i] }
}
report('stefanpochmann') {
(1..string.size).map { |i| string[0, i] }
}
report('stefanpochmann 2') {
Array.new(string.size) { |i| string[0, i+1] }
}
end