我有一個游戲專案,如果所選字母出現在秘密單詞中,我需要打動所選字母,但是當我嘗試在秘密單詞中捕獲所選字母的索引時,例如“a” “programador,代碼回傳給我“programador”這個詞的所有索引,而不僅僅是字母“a”所在的索引。
palavra_secreta = "programador"
letra_procurada = "a"
total_encontrado = palavra_secreta.count letra_procurada
palavra_secreta_array = palavra_secreta.split("")
puts palavra_secreta_array.each_with_index.select { |letra_procurada, index|
total_encontrado >= 1
}.map { |pair| pair[1] }
此代碼回傳我:0 1 2 3 4 5 6 7 8 9 10
uj5u.com熱心網友回復:
在處理要回傳其對應元素滿足特定條件的集合或字串的索引陣列的問題時,使用索引陣列通常很方便[0,1,..,n]。例如,如果想要回傳陣列arr = [3,2,6,5,4]中奇數元素的索引陣列,則可以撰寫以下1之一:
arr.each_index.select { |i| arr[i].odd? }
(0..arr.size-1).select { |i| arr[i].odd? }
arr.size.times.select { |i| arr[i].odd? }
全部回傳[0, 3]。
對于涉及字串的當前問題,我們可以使用上述最后兩種方法中的任何一種:
(0..palavra_secreta.size-1).select { |i| palavra_secreta[i] == letra_procurada }
palavra_secreta.size.times.select { |i| palavra_secreta[i] == letra_procurada }
兩者都回傳[5, 7]。
我相信這種方法讀起來很好,因為讀者應該可以立即清楚地看到正在回傳的索引選擇。
1. 我意識到在#2 中我可以撰寫(0...arr.size),但我發現混合使用兩點和三點范圍容易產生錯誤,所以當無法使用兩點范圍時,我只使用三點范圍。
uj5u.com熱心網友回復:
在您的代碼中,total_encontradois2大于或等于1。結果,您給出的條件#select始終為真,因此它選擇每個字符及其索引。然后,您將其映射到索引。
相反,您可能只想選擇匹配的字母letra_procurada。
palavra_secreta = "programador"
letra_procurada = "a"
total_encontrado = palavra_secreta.count letra_procurada
palavra_secreta_array = palavra_secreta.split("")
puts palavra_secreta_array
.each_with_index
.select { |letra, index| letra_procurada == letra }
.map { |pair| pair[1] }
您也可以使用#filter_map(Ruby 2.7 及更高版本)來簡化此操作。
palavra_secreta = "programador"
letra_procurada = "a"
total_encontrado = palavra_secreta.count letra_procurada
palavra_secreta_array = palavra_secreta.split("")
puts palavra_secreta_array
.each_with_index
.filter_map { |letra, index| index if letra_procurada == letra }
uj5u.com熱心網友回復:
您的select子句中的條件對于每個索引都是正確的,因為它只檢查total_encontrado變數并且該值在每次迭代中都不會改變。
puts palavra_secreta_array
.each_with_index
.select { |letra_procurada, index| total_encontrado >= 1 }
# ^^^^^^^^^^^^^^^^^^^^^
.map { |pair| pair[1] }
您想要的是選擇與猜測字符匹配的索引,因此您的條件可以改為:
puts palavra_secreta_array
.each_with_index
.select { |letra, index| letra == letra_procurada }
.map { |pair| pair[1] }
請注意,我必須將第一個引數的名稱更改為select塊。您在那里重新使用過,letra_procurada但這會影響實際letra_procurada變數。請記住,這select是為陣列中的每個元素呼叫塊并僅選擇該塊回傳 true 的元素,因此塊的第一個引數是陣列中的元素,如果您隱藏或忽略它,您將不知道你在塊內處理什么。
您也可以將其縮小一點并跳過split贊成使用String#each_char:
puts palavra_secrata
.each_char
.with_index
.select { |c, _| c == letra_procurada }
.map(&:last)
uj5u.com熱心網友回復:
"letra_procurada"意思是“想要的信”,所以你似乎覺得你必須像這樣傳遞你正在尋找的元素來選擇:
letra_procurada = "a"
palavra_secreta_array.each_with_index.select { |letra_procurada, index| }
# ^^^^^^^^^^^^^^^
但是,這根本不是塊引數或select特別是如何作業的。如果你用letra_procurada字串文字替換,你會立即得到SyntaxError:
palavra_secreta_array.each_with_index.select { |"a", index| }
# SyntaxError: unexpected string literal
塊包含您將塊傳遞給(此處:)的方法select可以呼叫的代碼(多次,僅一次或根本不呼叫)。在每次呼叫塊時,塊引數 ( |letra_procurada, index|)從方法(即 from select)傳遞到塊中。
您呼叫select,但select呼叫塊。這也稱為“回呼”。
在您的示例中,select為每個元素呼叫塊并將該元素作為塊引數傳遞,letra_procurada并且index. 然后它期望該塊回傳trueor false。該回傳值確定該元素是否將包含在結果中。
由于塊的第一個引數可以是任何字母,您可能需要一個更通用的變數名。像這樣的東西:
palavra_secreta_array.each_with_index.select { |letra, index|
# ...
}
一些例子可能有助于理解這一點。要僅選擇具有odd?索引的元素:
palavra_secreta_array.each_with_index.select { |letra, index|
index.odd?
}
#=> [["r", 1], ["g", 3], ["a", 5], ["a", 7], ["o", 9]]
僅選擇字母等于"r"或等于的元素"o":(||表示“或”)
palavra_secreta_array.each_with_index.select { |letra, index|
letra == "r" || letra == "o"
}
#=> [["r", 1], ["o", 2], ["r", 4], ["o", 9], ["r", 10]]
或組合,僅選擇具有"r"or字母"o"和奇數索引的元素:(&&表示“和”)
palavra_secreta_array.each_with_index.select { |letra, index|
(letra == "r" || letra == "o") && index.odd?
}
#=> [["r", 1], ["o", 9]]
如您所見,使用塊是一種非常靈活且強大的選擇元素的方法。
回到你的問題。您當前的塊只是檢查是否total_encontrado大于或等于1. 它不考慮當前字母或其索引。并且因為total_encontrado 大于,1所以塊總是回傳true并select回傳所有元素。
要僅選擇其字母與所需字母匹配的元素letra_procurada,您可以使用:
palavra_secreta_array.each_with_index.select { |letra, index|
letra == letra_procurada
}
#=> [["a", 5], ["a", 7]]
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/498153.html
