在 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
中字符的索引,要替换成刚才猜到的字母
我正在尝试找出一种方法,根据猜测其中一个数组中的字母,将两个数组过滤成一个数组。所以基本上是刽子手。但如果我有
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
中字符的索引,要替换成刚才猜到的字母