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

标签 ruby-on-rails ruby variables

有人可以向我解释一下,为什么不初始化 first_idxlast_idx 会导致代码无法运行??

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

我真的很感激一些(简单的)见解。谢谢!

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

最佳答案

block 中的变量

来自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], "e"=>[1], "l"=>[2, 9], "o"=>[4, 7], " "=>[5], "w"=>[6], "r"=>[8], "d"=>[10]}

关于ruby-on-rails - 为什么初始化变量如此重要?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41313367/

相关文章:

ruby-on-rails - 更改多态关联中的类型标识符

ruby-on-rails - rails : Using Eval to call another action

ruby-on-rails - Rails 新方法在控制台中有效,在 Controller 和浏览器中失败

javascript - 我可以使用变量的值来启动函数吗?

ruby-on-rails - 如何验证 Mongoid 中的数组不为空?

ruby-on-rails - Rails 嵌套资源和 :path => "/"

ruby-on-rails - PayPal 的 ActiveMerchant Poodle 补丁

ruby - rbenv 系统范围安装导致不安全操作

variables - 计算表中未知变量的数量

php - 太多的变量与数组