Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用ruby中字母表中的数字位置替换字符串中的字母_Ruby_String_Indexing_Methods_Replace - Fatal编程技术网

用ruby中字母表中的数字位置替换字符串中的字母

用ruby中字母表中的数字位置替换字符串中的字母,ruby,string,indexing,methods,replace,Ruby,String,Indexing,Methods,Replace,我试图创建一个方法,给定一个字符串,用它在字母表中的位置替换每个字母 如果文本中的任何内容不是一封信,我想忽略它,不返回它 "a" = 1, "b" = 2, etc. 范例 alphabet_position("The sunset sets at twelve o' clock.") 应返回“20 8 5 19 21 14 19 5 20 19 5 20 19 1 20 23 5 12 22 5 15 3 12 3 11”(作为

我试图创建一个方法,给定一个字符串,用它在字母表中的位置替换每个字母

如果文本中的任何内容不是一封信,我想忽略它,不返回它

"a" = 1, "b" = 2, etc.
范例

alphabet_position("The sunset sets at twelve o' clock.")
应返回
“20 8 5 19 21 14 19 5 20 19 5 20 19 1 20 23 5 12 22 5 15 3 12 3 11”
(作为字符串) 我试过这个,但没用:

    def alphabet_position(text)
      alph = ("a".."z").to_a
      text = text.split(/./).map {|ch| if ch.in?(alph)
        ((alph.index[ch]).to_i+1).to_s
        else
          ""
        end
      }.join(" ").strip
    end

提前谢谢

要调试一段代码,请逐行运行它。很快你就会发现:

日落时间定在十二点 text.split(/。/)#=>[] 它不会做你认为它会做的事

我想你的意思是:

text.split('') #=> ["T", "h", "e", " ", ...
text.chars #=> ["T", "h", "e", " ", ...

还有几个错误,但我将留给您去解决。

根据@Siim Liiser的答案,您也可以使用扫描方法获取字母

text = "The sunset sets at twelve o' clock."
irb(main):002:0> text.scan(/[a-z]/)
=> ["h", "e", "s", "u", "n", "s", "e", "t", "s", "e", "t", "s", "a", "t", "t", "w", "e", "l", "v", "e", "o", "c", "l", "o", "c", "k"]

如您所见,字母T为大写且缺失,要解决此问题,您可以在调用方法scan之前使用downcase:

irb(main):004:0> text.downcase.scan(/[a-z]/)
=> ["t", "h", "e", "s", "u", "n", "s", "e", "t", "s", "e", "t", "s", "a", "t", "t", "w", "e", "l", "v", "e", "o", "c", "l", "o", "c", "k"]

def字母表位置(文本)
text.downcase.split(“”).map do|字母|
索引=('a'..'z')。查找索引(字母)
索引+1如果索引
end.compact.join(“”)
结束

首先,我们可以构建转换,因为哈希查找非常快:

# alternatively letter_to_number = ('a'..'z').each.with_index(1).to_h
letter_to_number = ('a'..'z').zip(1..26).to_h 
#=> {"a"=>1, "b"=>2, "c"=>3, "d"=>4, "e"=>5, "f"=>6, 
#    "g"=>7, "h"=>8, "i"=>9, "j"=>10, "k"=>11, "l"=>12, 
#    "m"=>13, "n"=>14, "o"=>15, "p"=>16, "q"=>17, "r"=>18, 
#    "s"=>19, "t"=>20, "u"=>21, "v"=>22, "w"=>23, "x"=>24, "y"=>25, "z"=>26}
然后简单地把它们换掉

# ruby >= 2.7 
text.downcase.each_char.filter_map {|c| letter_to_number[c] }.join(' ')
# ruby < 2.7 
text.downcase.each_char.map {|c| letter_to_number[c] }.compact.join(' ')
#=> "20 8 5 19 21 14 19 5 20 19 5 20 19 1 20 20 23 5 12 22 5 15 3 12 15 3 11"
#ruby>=2.7
text.downcase.each_char.filter_map{| c | letter_to_number[c]}.join(“”)
#红宝石<2.7
text.downcase.each_char.map{c|letter_to_number[c]}.compact.join(“”)
#=> "20 8 5 19 21 14 19 5 20 19 5 20 19 1 20 20 23 5 12 22 5 15 3 12 15 3 11"

女士们先生们,发动你们的引擎

def alphabet_position(text)
  text.downcase.split('').map do |letter|
    index = ('a'..'z').find_index(letter)
    index + 1 if index
  end.compact.join(' ')
end

您可能希望在循环之外构建
('a'..'z')
,这样就不会创建N个范围,其中N等于text.size。我不知道这是否非常重要,但您不需要对范围进行线性扫描以获得字母表中字符的偏移量,因为您可以减去ascii码。我不知道用ruby怎么做。另外,在第4行,零真值在ruby中吗?“a”可能有一个bug。不知道您是否尝试过它,但我发现
果味
gem在基准测试方面比内置的更好。对常量btw的调用很好,除了它比
字母表位置
提供了不公平的优势,后者可以实现相同的功能。@engineersmnky,我已经使用了
水果
很多次,在这里体验之后,我会回到它。最初我有效地使用了
1.times{method(m).call(str)}
,从一次运行到下一次运行的结果遍布地图。定义一个常量似乎很公平,因为这种方法通常会被多次调用。我不理解你关于
字母表位置的评论。我的意思是,正如我在帖子下评论的那样,范围(
('a'..'z')
)可以在循环之外构造,在这种情况下,可以在方法本身之外构造(这是额外节省时间的地方,介于
smnky\u pre\u 1\u 7
smnky\u pre\u w\u常量之间)。这也是我喜欢的
furty
,因为它是确定性的,你不必太在意跑步次数或跑步之间的个体差异。@engineersmnky,是的,但是
find\u index
仍然是一个线性搜索,不是吗?对于furty-smnky\u pre\u 2\u 7\u,w\u常数类似于cary\u with\u arr;cary\u with\arr与cary相似;cary比smnky_pre_2_7快3倍±1.0;smnky_pre_2_7比tatiana快2倍±1.0;*repl.它仍在使用2.5.1,因此我不得不删除2.7选项。
convert "Sunset was at twelve o'clock, somewhere, on some day"
  #=> "19 21 14 19 5 20 23 1 19 1 20 20 23 5 12 22 5 15 3 12 15 3 11 19 15 13 5 23 8 5 18 5 15 14 19 15 13 5 4 1 25"
def alphabet_position(text)
  text.downcase.split('').map do |letter|
    index = ('a'..'z').find_index(letter)
    index + 1 if index
  end.compact.join(' ')
end
def smnky_1_7(str)
  letter_to_number = ('a'..'z').zip(1..26).to_h
  str.downcase.each_char.filter_map {|c| letter_to_number[c] }.join(' ')
end
def smnky_pre_1_7(str)
  letter_to_number = ('a'..'z').zip(1..26).to_h
  str.downcase.each_char.map {|c| letter_to_number[c] }.compact.join(' ')
end
LETTER_TO_NUMBER = ('a'..'z').zip(1..26).to_h
def smnky_pre_w_constant(str)
  str.downcase.each_char.map {|c| LETTER_TO_NUMBER[c] }.compact.join(' ')
end
def convert_with_arr(str)
  str.downcase.each_char.with_object([]) do |c,arr|
    n = c.ord
    arr << n - 96 if n.between?(97, 122)
  end.join(' ')
end
str = "Sunset was at twelve o'clock, somewhere, on some day"
require 'benchmark'
def run(m, str)
  500.times { method(m).call(str) }
end
Benchmark.bm(19) do |x|
  x.report("Cary")                 { run(:convert, str) }
  x.report("Tatiana")              { run(:alphabet_position, str) }
  x.report("smnky 1.7")            { run(:smnky_1_7, str) }
  x.report("smnky pre 1.7")        { run(:smnky_1_7, str) }
  x.report("smnky pre w/constant") { run(:smnky_pre_w_constant, str) }
  x.report("Cary with arr")        { run(:convert_with_arr, str) }
end
                          user     system      total        real
Cary                  0.018610   0.000300   0.018910 (  0.019135)
Tatiana               0.067738   0.001138   0.068876 (  0.070317)
smnky 1.7             0.028659   0.001035   0.029694 (  0.030583)
smnky pre 1.7         0.032050   0.001662   0.033712 (  0.035089)
smnky pre w/constant  0.013705   0.000323   0.014028 (  0.014139)
Cary with arr         0.016989   0.000538   0.017527 (  0.017925)