如何在 Ruby 循环中的第一次迭代中采取不同的行动?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8181390/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 04:30:39  来源:igfitidea点击:

How to act differently on first iteration in a Ruby loop?

ruby

提问by Panagiotis Panagi

I always use a counter to check for the first item (i==0) in a loop:

我总是使用计数器来检查i==0循环中的第一项 ( ):

i = 0
my_array.each do |item|
  if i==0
    # do something with the first item
  end
  # common stuff
  i += 1
end

Is there a more elegant way to do this (perhaps a method)?

有没有更优雅的方法来做到这一点(也许是一种方法)?

回答by detunized

You can do this:

你可以这样做:

my_array.each_with_index do |item, index|
    if index == 0
        # do something with the first item
    end
    # common stuff
end

Try it on ideone.

ideone试试

回答by Russell

Using each_with_index, as others have described, would work fine, but for the sake of variety here is another approach.

使用each_with_index,正如其他人所描述的,将做工精细,但对于不同的缘故这里是另一种方法。

If you want to do something specific for the first element only and something general for all elements including the first, you could do:

如果您只想为第一个元素做一些特定的事情,而对包括第一个元素在内的所有元素做一些通用的事情,您可以这样做:

# do something with my_array[0] or my_array.first
my_array.each do |e| 
  # do the same general thing to all elements 
end

But if you want to not do the general thing with the first element you could do:

但是如果你不想用第一个元素做一般的事情,你可以这样做:

# do something with my_array[0] or my_array.first
my_array.drop(1).each do |e| 
  # do the same general thing to all elements except the first 
end

回答by undur_gongor

What fits best is depending on the situation.

什么最合适取决于具体情况。

Another option (if you know your array is not empty):

另一种选择(如果您知道您的数组不为空):

# treat the first element (my_array.first)
my_array.each do | item |
   # do the common_stuff
end

回答by Toby Hede

Arrays have an "each_with_index" method which is handy for this situation:

数组有一个“each_with_index”方法,在这种情况下很方便:

my_array.each_with_index do |item, i|
  item.do_something if i==0
  #common stuff
end

回答by Telemachus

each_with_indexfrom Enumerable(Enumerable is already mixed in with Array, so you can call it on an array without any trouble):

each_with_index来自Enumerable(Enumerable 已经与 Array 混合在一起,因此您可以毫无困难地在数组上调用它):

irb(main):001:0> nums = (1..10).to_a
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
irb(main):003:0> nums.each_with_index do |num, idx|
irb(main):004:1* if idx == 0
irb(main):005:2> puts "At index #{idx}, the number is #{num}."
irb(main):006:2> end
irb(main):007:1> end
At index 0, the number is 1.
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

回答by steenslag

If you don't need the array afterwards:

如果您之后不需要该数组:

ar = %w(reversed hello world)

puts ar.shift.upcase
ar.each{|item| puts item.reverse}

#=>REVERSED
#=>olleh
#=>dlrow

回答by sarnold

Ruby's Enumerable#injectprovides an argument that can be used for doing something differently on the first iteration of a loop:

RubyEnumerable#inject提供了一个参数,可用于在循环的第一次迭代中做一些不同的事情:

> l=[1,2,3,4]
=> [1, 2, 3, 4]
> l.inject(0) {|sum, elem| sum+elem}
=> 10

The argument is not strictly necessary for common things like sums and products:

对于诸如总和和乘积之类的常见事物,该参数并不是绝对必要的:

> l.inject {|sum, elem| sum+elem}
=> 10

But when you want to do something differenton the first iteration, that argument might be useful to you:

但是当你想在第一次迭代中做一些不同的事情时,这个论点可能对你有用:

> puts fruits.inject("I like to eat: ") {|acc, elem| acc << elem << " "}
I like to eat: apples pears peaches plums oranges 
=> nil

回答by android.weasel

Here's a solution that doesn't need to be in an immediately enclosing loop and avoids the redundancy of specifying a status placeholder more than once unless you really need to.

这是一个不需要立即封闭循环的解决方案,并且避免了多次指定状态占位符的冗余,除非您确实需要。

do_this if ($first_time_only ||= [true]).shift

Its scope matches the holder: $first_time_onlywill be globally once; @first_time_onlywill be once for the instance, and first_time_onlywill be once for the current scope.

它的范围与持有者匹配:$first_time_only将是全球性的一次;@first_time_only对于实例first_time_only将是一次,对于当前范围将是一次。

If you want the first several times, etc, you can easily put [1,2,3]if you need to distinguish which of the first iterations you're in, or even something fancy [1, false, 3, 4]if you need something weird.

如果你想要前几次,等等,你可以很容易地把[1,2,3]你是否需要区分你在第一个迭代中的哪个,或者[1, false, 3, 4]如果你需要一些奇怪的东西,甚至是一些花哨的东西。