ruby-on-rails – 为什么初始化变量如此重要?

前端之家收集整理的这篇文章主要介绍了ruby-on-rails – 为什么初始化变量如此重要?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
请有人向我解释,为什么不初始化first_idx和last_idx会导致代码无法运行?

当我运行它时,我得到这个错误“未定义的局部变量或方法last_idx”.我知道建议是始终初始化变量,但我不明白为什么.毕竟first_idx和last_idx总是会在循环中得到一个值,因为参数字母总是出现在字符串中(在这个特殊的问题中).

我真的很感激一些(简单的)洞察力.谢谢!

P.S,我也知道在Ruby中使用#index和#rindex很容易解决问题,但是我不允许使用简单的方法解决它.

def find_for_letter(string,letter)

first_idx = nil
0.upto(string.length - 1) do |idx1|
    if string[idx1] == letter
        first_idx = idx1
        break
    end
end

last_idx = nil
(string.length - 1).downto(0) do |idx2|
    if string[idx2] == letter
        last_idx = idx2
        break
    end
end

if last_idx == first_idx
    return [first_idx]
else
    return [first_idx,last_idx]
end
end



def first_last_indices(word)
    h = {}
    word.chars.each do |char|
        h[char] = find_for_letter(word,char)
    end
    h
end

解决方法

块中的变量

Ruby Programming Language

Blocks define a new variable scope: variables created within a block
exist only within that block and are undefined outside of the block.
Be cautIoUs,however; the local variables in a method are available to
any blocks within that method. So if a block assigns a value to a
variable that is already defined outside of the block,this does not
create a new block-local variable but instead assigns a new value to
the already-existing variable.

a = 0

2.times do
  a = 1
end

puts a #=> 1

b = 0

2.times do |i;b| # <- b will stay a block-local variable 
  b = 1
end

puts b #=> 0

2.times do |i|
  c = 1
end

puts c #=> undefined local variable or method `c' for main:Object (NameError)

重构您的代码

用字符和索引迭代

这是一个较小的方法来实现目标.
它为每个字符保留一个带有minmax索引的哈希值.

默认哈希值是一个空数组.

方法遍历每个字符(带索引).

如果minmax数组已包含2个值:

>它用当前索引替换第二个(最大).
>它会向数组添加当前索引.

def first_last_indices(word)
  minmax_hash = Hash.new { |h,k| h[k] = [] }
  word.each_char.with_index do |char,index|
    minmax = minmax_hash[char]
    if minmax.size == 2
      minmax[1] = index
    else
      minmax << index
    end
  end
  minmax_hash
end

p first_last_indices('hello world')
{"h"=>[0],"e"=>[1],"l"=>[2,9],"o"=>[4,7]," "=>[5],"w"=>[6],"r"=>[8],"d"=>[10]}

使用group_by

这是另一种可能性.它使用group_by获取每个字符的所有索引,而minmax获取第一个和最后一个索引:

def first_last_indices(word)
  word.each_char.with_index
      .group_by{ |c,_| c }.map{ |c,vs|
        [c,vs.map(&:last).minmax.uniq]
      }.to_h
end

p first_last_indices('hello world')
{"h"=>[0],"d"=>[10]}
原文链接:https://www.f2er.com/ruby/267531.html

猜你在找的Ruby相关文章