我需要使用for
循环从more_stuff
数组中取出最后四个字符串。
这是我的代码:
# assigns string Apples Oranges Crows Telephone Light Sugar to variable
ten_things
ten_things = "Apples Oranges Crows Telephone Light Sugar"
# prints Wait there are not ten things on that list. Let's fix that.
puts "Wait there are not 10 things in that list. Let's fix that."
# first seperates string ten_things into an array at space character, then
# assigns the new array to variable stuff
stuff = ten_things.split(' ')
# assigns array to more stuff with strings, Day, Night, Song, Frisbee, Girl,
# and Boy
more_stuff = ["Day", "Night", "Song", "Frisbee", "Corn", "Banana", "Girl",
"Boy"]
# using math to make sure there's 10 items
# assigns fifth through eighth elements in array more_stuff to array stuff_3
stuff_3 = more_stuff[4..8]
# prints array stuff_3 in brackets
puts "#{stuff_3}"
# for all strings in stuff_3
stuff_3.each do |stuff_3|
# pops the last item off of stuff_3
next_one = stuff_3.pop
# puts adding (next_one)
puts "Adding #{next_one}"
# adds (next_one) to array stuff
stuff.push(next_one)
# ends for loop
end
此处还出现了从Powershell运行时出现的错误:
Wait there are not 10 things in that list. Let's fix that.
["Corn", "Banana", "Girl", "Boy"]
ex38for.rb:17:in `block in <main>': undefined method `pop' for "Corn":String
(NoMethodError)
from ex38for.rb:16:in `each'
from ex38for.rb:16:in `<main>'
我很困惑for
循环如何工作,特别是each
以及将数据放入数组命令的位置。
答案 0 :(得分:3)
pop
的作用是获取数组的最后一个元素或值(在没有指定元素数的情况下使用时):
p stuff_3.pop
# => "Boy"
p stuff_3.pop(2)
# => ["Banana", "Girl"]
但在您的情况下,您尝试将pop
与主数组中的元素一起使用。
如果您在each
方法之外检查它:
puts stuff_3.pop
# => Boy
然后会打印Boy
因为stuff_3
数组中您声明为more_stuff[4..8]
的最后一个元素:
stuff_3 = more_stuff[4..8]
p stuff_3
# => ["Corn", "Banana", "Girl", "Boy"]
但是,当您执行stuff_3.each do |stuff_3|
时,您使用相同的名称stuff_3
来访问该阵列中具有相同名称的每个元素。因此,您undefined method 'pop' for "Corn":String
会收到pop
错误,因为array
正在等待stuff_3
,如果您遍历String
内的每个元素,那么#39;重新获得each
元素。
一种可能的解决方案是,当您将stuff_3
与stuffs
数组一起使用时,使用其他名称来访问这些元素,可能就像stuff_3
一样,这将为您提供&# 34;添加男孩&#34;和#34;添加女孩&#34;。
或者也许任何一个词来引用_
内的元素与这个元素不同可能有用,因为你没有访问这些元素,你也可以使用stuff_3.each do |_|
next_one = stuff_3.pop
puts "Adding #{next_one}"
stuff.push(next_one)
end
来指定它们&#39 ;没有被使用:
stuff
在推送元素之前,这将是["Apples", "Oranges", "Crows", "Telephone", "Light", "Sugar"]
:
["Apples", "Oranges", "Crows", "Telephone", "Light", "Sugar", "Boy", "Girl"]
之后:
{{1}}
答案 1 :(得分:2)
你正在遮蔽外部变量:
stuff_3.each do |stuff_3|
stuff_3.pop
在这段代码中,&#34;内部&#34; stuff_3
变量优先于&#34;外部&#34; stuff_3
变量。
这就是您看到错误消息的原因:
未定义的方法`pop&#39; for&#34; Corn&#34;:String
像这样隐藏外部变量通常被认为是不好的做法,因为它会导致令人困惑的代码和&#34;意外的&#34;行为(就像你在这里找到的那样!)。一个简单的解决方法是使用不同的变量名称:
stuff_3.each do |stuff_3_item|
stuff_3.pop
......虽然我认为你在这里尝试做的事情应该有所不同 - 例如。
stuff_3.each do |stuff_3_item|
puts "Adding #{stuff_3_item}"
stuff.push(stuff_3_item)
end
答案 2 :(得分:0)
让我们关注代码的这一部分:
stuff_3.each do |stuff_3|
# pops the last item off of stuff_3
next_one = stuff_3.pop
# puts adding (next_one)
puts "Adding #{next_one}"
# adds (next_one) to array stuff
stuff.push(next_one)
# ends for loop
end
此代码:stuff_3.each do |stuff_3|
是一个循环,它接收stuff_3
中的每个项目,将其保存到本地变量(您也称为stuff_3
)并使用它执行以下代码
所以当你调用stuff_3.pop
时,你实际上是在只包含一个项目的局部变量上调用pop
,而不是包含所有项目的数组。因此,您会收到错误:
未定义的方法`pop'为“Corn”:String
这告诉您,您在单个项目(本例中为字符串“Corn”)上调用pop
,而不是像您预期的那样调用项目数组。
解决此问题的一种方法是更改代码:
stuff_3.each do |next_one|
# puts adding (next_one)
puts "Adding #{ next_one }"
# adds (next_one) to array of stuff
stuff.push(next_one)
# ends for loop
end
此代码将遍历stuff_3
中的每个项目,并将其添加到stuff
。但它的工作方式可能与您预期的不同:
stuff_3.each
会从头到尾遍历项目,而pop
会先取最后一项,这意味着此代码会以相反的顺序向您的数组中添加项目。stuff_3.each
会在不删除项目的情况下浏览项目,而pop
会删除每个项目,最终会将stuff_3
数组留空。如果您不想要这些变体,您仍然可以像这样使用pop
:
stuff_3.times do |i|
#pops the last item off of stuff_3
next_one = stuff_3.pop
# puts adding (next_one)
puts "Adding #{next_one}"
# adds (next_one) to array of stuff
stuff.push(next_one)
# ends for loop
end
此代码使用stuff_3.times
执行循环次数与stuff_3中的项目一样多次。因此,如果stuff_3中有3个项目,则循环执行3次。变量i
是一个从0开始的计数器,每次执行循环时都会计数。在这种情况下,times
的工作方式与传统的for循环非常相似,上述代码的执行方式与您预期的执行完全相同。