0

我正在学习使用 Ruby 构建hangman 应用程序的教程。它有一个隐藏单词的功能 masquerade,它只是从文件中导入的国家名称。问题是我不明白这实际上是如何掩盖这些词的,或者三元运算符是如何在注入中工作的。它正在检查字符是否为空白(即“”),如果是,则将其设置为空白(即“”),但如果不是,则将其设为  。该函数似乎没有处理单词具有实际字符(即字母)的事实。

谁能解释这种菜鸟,我误解了什么?另外,为什么它在最后(在结束之前)再次添加“伪装”?

def masquerade(word)

      word.each_char.inject([]) { |disguise, char| disguise << (char == " " ? " " : "&nbsp;"); disguise }

end

游戏词举例

Afghanistan
Albania
Algeria
Andorra
Angola
Antigua & Deps
Argentina
Armenia

整个Word课

class Word

  class << self
    def get_random
      content = File.read("countries.txt")
      words = content.split("\n")
      words[rand(words.size)].upcase
    end

    def masquerade(word)
      word.each_char.inject([]) { |disguise, char| disguise << (char == " " ? " " : "&nbsp;"); disguise }
    end

    def reveal(last_revealed_word, char_clicked, final_word)
      chars = final_word.each_char.to_a

      last_revealed_word.each_index do |i|
        last_revealed_word[i] = chars[i] if last_revealed_word[i] == "&nbsp;" and chars[i] == char_clicked
      end
    end

    def chars_left(revealed_word)
      revealed_word.count { |c| c == "&nbsp;" }
    end

  end

end
4

2 回答 2

1

让我们假设 word = 'Albania'。word.each_char 返回一个 Enumerable 对象,其中每个“项目”都是单词中的一个字母。

想象一下使用#each 而不是#inject

word.each_char.each { |letter| puts letter }
A
l
b
...

#inject 旨在获取枚举中的所有项目,并以某种方式组合它们。在这种情况下,它们被组合成一个数组。您可以看出这是因为将一个空数组作为 .inject([]); 中的参数传递给注入。它也可能是注入(Array.new)。无论传入什么,都将成为注入“备忘录”的默认值,该对象用于在遍历项目时跟踪最终结果。在这种情况下,该备忘录对象称为伪装。

在注入循环期间,伪装备忘录将从一次迭代传递到下一次迭代。每次迭代都将处理调用注入的枚举中的一项(字母)。在块内,该项目称为 char。

无论块返回什么,都将成为下一次注入迭代的备忘录(伪装)的新值。

所以在这里,第一次迭代将有 disguise=[] 和 char='A'。if/else 表示“如果 char 是单个空格,则将单个空格附加到伪装数组,否则,将不间断空格附加到伪装数组。

Array#push() 的结果(这是 << 在这里所做的),是新项目被推送后的数组。因此,如果您有 [1,2].push(3),则返回 [1,2,3]。在这种注入的情况下,他们希望将推送的结果传递给下一次迭代,因此基本上通过伪装来确保数组是块返回的内容;在最后。就目前而言,没有必要。如果在 push 和块结束之间发生了其他操作,则需要显式返回伪装数组,否则第二次操作的结果将存储在备忘录中。

至于 if/else 如何处理单词的字母,基本上任何时候它都是它放在   字符串中的字母。

因此,在第一次迭代中,char='A' 不是单个空格,因此 nbsp 被推入空数组,并且该数组 [" "] 由块返回。伪装现在等于 [" "]。在第二次迭代中,char='l',也不是空格,所以另一个   被推入数组,变成 [" ", " "]。这就是第三次迭代中block的结果和disguise的值。

对于所有字母,注入将继续这样,然后返回伪装的最终值。

在大多数情况下,这将导致 [" ", " ", " ", etc],或者如果国家名称中有空格,您将得到 [" ", " ",  "," ", “”等]。如果不了解结果数组是如何在视图中使用或以某种方式呈现给用户的,就很难说出其中的意义。

  • 我删除了 ; 来自 nbsp,所以他们会出现。
于 2012-10-02T20:54:48.157 回答
1

disguise不需要在最后添加。已经改变了<<对象。

你看不出有什么区别:

[1] pry(main)> "wor d".each_char.inject([]) { |d, c| d << ( c == " " ? " " : "&nbsp;"); d }
=> ["&nbsp;", "&nbsp;", "&nbsp;", " ", "&nbsp;"]

[2] pry(main)> "wor d".each_char.inject([]) { |d, c| d << ( c == " " ? " " : "&nbsp;") }
=> ["&nbsp;", "&nbsp;", "&nbsp;", " ", "&nbsp;"]

upd:这里的屏蔽是用不间断的空格替换字符

于 2012-10-02T20:31:43.840 回答