在 ruby 中将两个字符串过滤为 1 的最佳方法

best way to filter two strings into 1 in ruby

我正在尝试找出一种方法,根据猜测其中一个数组中的字母,将两个数组过滤成一个数组。所以基本上是刽子手。但如果我有

word_array = ["b", "u", "s", "b", "o", "i"]
hidden_array = Array.new(word_array.length, "-")

p hidden_array

然后我想打印到控制台 ["b",“-”,“-”,"b",“-”,“-”] 如果 "b"猜到了。创建这个会随时间变化的数组的初学者好方法是什么?它应该是哈希吗?谢谢!

您可以在一个数组中跟踪找到的字母并创建一个方法来进行打印

word_array = ["b", "u", "s", "b", "o", "i"]
found_letters = []
def hangman_prompt(found_letters)
  word_array.map do |char|
    found_letters.include?(char) ? char : "-"
  end.join(" ")
end

然后你可以像这样在输入循环中使用它:

loop do
  puts hangman_prompt(found_letters)
  puts "what is your guess?"
  input = gets.chomp
  if word_array.include? input
    found_letters << input
  end
end

我在这里使用 Array#map 创建一个相同长度的新数组。每个原始数组项都传递给块,块决定如何将它们复制到新数组。

一种方法:

word_array = ["b", "u", "s", "b", "o", "i"]
word_array_i = word_array.map.with_index { |e,i| [e,i] }                                                
#=> [["b", 0], ["u", 1], ["s", 2], ["b", 3], ["o", 4], ["i", 5]] 
p hidden_array = Array.new(word_array.length, "_")

until hidden_array == word_array
  puts 'make a guess'
  guess = gets.chomp
  if word_array.include? guess
    puts 'correct guess'
    ar = word_array_i.select { |arr| arr.first == guess }
                     .flatten.select { |e| e.class == Fixnum }
    ar.each { |e| hidden_array[e] = guess }
  else
    puts 'incorrect guess'
  end
  p hidden_array
  puts
end
puts 'game complete'

研究的关键方法 here Array#include?, Enumerator#with_index.

到目前为止所有的解决方案都围绕着数组,但不要忘记字符串基本上是一个 字符数组。只需使用字符串:

word = 'busboi'
guesses = 'bs'

word.tr('^'+guesses, '-')
# => "b-sb--"

String#tr 方法将第一个参数中的所有字母转换为第二个参数中的映射,因此您可以执行 ROT13、简单密码等操作,或者在这种情况下使用否定功能 ^ 反转第一组并替换所有不匹配的字符。

我不会使用数组,只会使用字符串。

代码

def replace_underscores(word, hidden_word, guess)
  word.scan(Regexp.new(guess)) { hidden_word[Regexp.last_match.begin(0)] = guess }
  hidden_word
end

例子

word = "busboi" 
hidden_word = "_" * word.length
  #=> "______"

replace_underscores(word, hidden_word, "a") # guess "a"
  #=> "______"
replace_underscores(word, hidden_word, "b") # guess "b"
  #=> "b__b__"                                            
replace_underscores(word, hidden_word, "r") # guess "r"
  #=> "b__b__" 
replace_underscores(word, hidden_word, "o") # guess "o"
  #=> "b__bo_" 
replace_underscores(word, hidden_word, "u") # guess "u"
  #=> "bu_bo_" 
replace_underscores(word, hidden_word, "s") # guess "s"
  #=> "busbo_" 

检查 hidden_word 是否被猜中:

def guessed?(hidden_word)
  hidden_word.count('_').zero?
end

guessed?(hidden_word)   
  #=> false

让我们再猜一猜。

replace_underscores(word, hidden_word, "i") # guess "i"
  #=> "busboi" 

guessed?(hidden_word)   
  #=> true

备注

我用的方法String#scan with a block that is executed for each match. Within the block the MatchData object is retrieved with the class method Regexp::last_match. (Alternatively, one could substitute the global variable $~ for Regexp.last_match. For details, search for "special global variables" at Regexp.) The method MatchData.begin是用来获取str中字符的索引,要替换成刚才猜到的字母