我试图从用户扫描一串原始输入并返回一个由带有(TOKEN,WORD)配对的数组数组成的句子。如果一个单词不是词典的一部分,那么它仍然应该返回WORD但是将TOKEN设置为错误标记。
在方法“@@ dictionary.each do | type,list |”中只要将else语句设置为返回nil,初始if语句在构建找到的单词的键/值数组时工作正常。但是,当我尝试将错误/单词对放入数组中以用于未包含在@@字典散列中的单词(即那些属于代码的else部分的单词)时,我会在数组中为每个单词接收5个单独的对用户输入的内容,对于输入的每个单词,每个键的每次迭代一次。
有没有人知道如何只返回一个错误/值对数组,而不是每个单词的五次迭代中的每一个都返回一个?
class Lexicon
@@dictionary = {
'direction' => ['north', 'south', 'east', 'west', 'down', 'up', 'left', 'right', 'back'],
'verbs' => ['go', 'stop', 'kill', 'eat'],
'stop words' => ['the', 'in', 'of', 'on', 'at', 'it'],
'nouns' => ['door', 'bear', 'princess', 'cabinet'],
'numbers' => [0..9]
}
stuff = $stdin.gets.chomp
@@words = stuff.split(' ')
def self.scan
result = []
@@words.each do |text_element|
categorized = []
@@dictionary.each do |type, list|
if
list.include?(text_element.downcase)
categorized = [type, text_element]
result.push(categorized)
else
nil
#categorized = ["ERROR", text_element]
#result.push(categorized)
end
end
end
print result
end
Lexicon.scan
end
它发生的原因是每次遍历所有元素,并且它只有一次或从不。
减少代码可以帮助您了解发生的情况:
dictionary = {
'direction' => ['north', 'south'],
'verbs' => ['go', 'stop', 'kill', 'eat'],
'whathever' => ['blah']
}
text = 'go'
dictionary.each do |type, list|
if p list.include?(text) # added p
then
p text
else
p 'error'
end
end
它返回:
# false
# "error"
# true
# "go"
# false
# "error"
您需要一种不同的方法,例如:
text = 'nothing'
result = dictionary.find { |_, v| v.include? text }
result ? [result.keys, text] : "Error"
虽然可能会觉得组织按字典对字典进行分类,但这样做既简化又快得多,因为字典要被展平并且默认设置为'ERROR'标记。
例如:
@@dictionary = {
'direction' => ['north', 'south', 'east', 'west', 'down', 'up', 'left', 'right', 'back'],
'verbs' => ['go', 'stop', 'kill', 'eat'],
...
变成这样:
@@dictionary = {
'north' => 'direction',
'south' => 'direction',
...
'go' => 'verbs',
'stop' => 'verbs',
...
}
@@dictionary.default = 'ERROR'
这样,您的查找变为线性,没有不必要的布尔逻辑,就像这样。
def scan
result = stuff.split(' ').map do |word|
[@@dictionary[word.downcase], word]
end
print result
end
这对我有用。感谢Sebastian School的简化字典的想法。
class Lexicon
@@dictionary = {
'direction' => ['north', 'south', 'east', 'west', 'down', 'up', 'left', 'right', 'back'],
'verbs' => ['go', 'stop', 'kill', 'eat'],
'stop words' => ['the', 'in', 'of', 'on', 'at', 'it'],
'nouns' => ['door', 'bear', 'princess', 'cabinet'],
'numbers' => [0..9]
}
stuff = $stdin.gets.chomp
@@words = stuff.downcase.split(' ')
def self.scan
result = []
values = []
@@dictionary.each do |key, value|
values << value
end
value_list = values.flatten.uniq
@@words.each do |text_element|
if value_list.include?(text_element)
@@dictionary.each do |key, value|
if value.include?(text_element)
categorized = [key, text_element]
result.push(categorized)
else
nil
end
end
else
result.push(["Error, #{text_element}"])
end
end
print result
end
Lexicon.scan
end