Arrays Ruby(v2.3.1).split数组上的每个方法不按任何逻辑顺序
我有一个简单的字符串: 西北东南 我想将其拆分为子字符串,并将其作为子数组放到一个数组中,即:Arrays Ruby(v2.3.1).split数组上的每个方法不按任何逻辑顺序,arrays,ruby,string,each,Arrays,Ruby,String,Each,我有一个简单的字符串: 西北东南 我想将其拆分为子字符串,并将其作为子数组放到一个数组中,即: [["direction", "north"], ["direction", "south"], ["direction", "east"], ["direction", "west"]] 但是,每个方法似乎既不能按字母顺序处理元素,也不能按元素输入的顺序处理元素 .each方法似乎按以下顺序处理拆分字符串: 北第一子字符串[按字母顺序第二] 南第三子字符串[按字母顺序第三] 西第二子字符串[按字母
[["direction", "north"], ["direction", "south"], ["direction", "east"], ["direction", "west"]]
但是,每个方法似乎既不能按字母顺序处理元素,也不能按元素输入的顺序处理元素
.each方法似乎按以下顺序处理拆分字符串:
北第一子字符串[按字母顺序第二]
南第三子字符串[按字母顺序第三]
西第二子字符串[按字母顺序最后一个]
east last子字符串[按字母顺序排列的第一个]
它肯定不会按字母顺序遍历子字符串,也不会按相反顺序遍历子字符串,而是从第一个子字符串开始,最后一个子字符串结束,并切换中间的字符串
我就是想不出来
这是我的密码:
class Lexicon
def scan(stuff)
words = stuff.split
#Empty arrays to easily push split words into
@direction_array = []
#Lexicons of different kinds of words
@directions = ["north", "south", "east", "west", "down", "up", "left", "right", "back"]
puts "This the original set"
print words, "\n"
while words.any? == true
words.each do |word|
if @directions.include? word
puts "This is the word I selected: #{word}"
@direction_array.push(['direction', word])
words.delete word
print @direction_array
puts "This is what remains in the words set: #{words}"
else
"This word does not belong."
words.delete word
# puts "This is what remains in the words set: #{words}"
end
end
end
if @direction_array.any? == true
puts "This is what we have in the direction array:"
print @direction_array, "\n"
return @direction_array
else
puts "Nothing to show for our efforts"
end
end
end
testing = Lexicon.new()
testing.scan("north south east west")
以下是一些关于如何使Ruby更加传统的想法:
class Lexicon
# Declare things that are repeatedly used without being modified as
# constants at the class-level.
DIRECTIONS = %w[ north south east west down up left right back ]
def scan(stuff)
# Split the string and select all the words that are present
# in the DIRECTIONS above.
stuff.split.select do |word|
DIRECTIONS.include?(word)
end.map do |word|
# Transform these into [ 'direction', x ] pairs
[ 'direction', word ]
end
end
end
如果您将代码组织成整洁、简洁的块,将意图表示为一系列简单的转换,那么代码就变得非常容易理解。注意,这里不需要显式返回,因为默认情况下该操作是隐式返回的
要练习它,您可以获得以下信息:
testing = Lexicon.new
testing.scan("north south east west")
# => [["direction", "north"], ["direction", "south"], ["direction", "east"], ["direction", "west"]]
p方法在显示变量内容方面非常方便,测试任意代码的irb工具也是如此
我认为您的原始代码中的一些问题来自于使用迭代和删除方法,而不是使用拒绝或选择的过滤方法。从您正在积极迭代的数组中删除内容通常会适得其反,而且由于从数组中删除内容实际上在计算上非常昂贵,因此只构建您想要的元素的新数组更容易。如果从数组中删除元素,然后,删除元素留下的孔右侧的所有元素都向左移动以填充间隙
dirs = "north west south east".split
#=> ["north", "west", "south", "east"]
["direction"].product(dirs)
#=> [["direction", "north"], ["direction", "west"],
# ["direction", "south"], ["direction", "east"]]
在数组上迭代时,正在从数组中删除元素。如果您只删除尚未迭代的元素,那就可以了。但是,如果删除一个已经迭代过的元素,则删除元素右侧的所有元素(包括下一个将要迭代的元素)都会向左移动,以填充删除元素留下的洞,从而跳过下一个元素
在对数据结构进行迭代时,您永远不应该对其进行变异,除非明确说明这是一件安全的事情。您可以采取以下方法:
"north west south east".split.collect { |direction| ['direction', direction] }
将方向拆分为数组的元素,然后按要求收集它们。最好摆脱添加诸如while x==true或if x==true之类的不必要代码的习惯,因为while x几乎总是能够完成这项工作,特别是在有需要的情况下?将只返回true或false。这比我的代码优雅得多,我将花一些时间确保我理解这一点。谢谢你,没有比这更容易的了。注意:您可以使用拆分定义dir,它将与问题完全匹配。