如何在Ruby

时间:2017-05-18 16:15:48

标签: arrays ruby for-loop

我需要使用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以及将数据放入数组命令的位置。

3 个答案:

答案 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_3stuffs数组一起使用时,使用其他名称来访问这些元素,可能就像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循环非常相似,上述代码的执行方式与您预期的执行完全相同。