我总是使用计数器来检查i==0
循环中的第一项():
i = 0
my_array.each do |item|
if i==0
# do something with the first item
end
# common stuff
i += 1
end
有没有更优雅的方法可以做到这一点(也许是一种方法)?
我总是使用计数器来检查i==0
循环中的第一项():
i = 0
my_array.each do |item|
if i==0
# do something with the first item
end
# common stuff
i += 1
end
有没有更优雅的方法可以做到这一点(也许是一种方法)?
each
仅对常见内容进行常规循环?
array.first
或表示array[0]
),然后运行each
循环,如果他也不想对第一项做常规的事情,他仍然必须测试第一项。
my_array[1..-1].each
吗?
Answers:
你可以这样做:
my_array.each_with_index do |item, index|
if index == 0
# do something with the first item
end
# common stuff
end
在ideone上尝试一下。
.each_with_index
代替.each
。以下.drop(1)
建议似乎更像红宝石,并且完全避免使用索引。
if index > 1
并得到了错误 undefined method '>' for nil:NilClass
使用each_with_index
,正如其他人所描述的,将做工精细,但对于不同的缘故这里是另一种方法。
如果只想对第一个元素进行特定操作,而对所有元素(包括第一个元素)进行常规操作,则可以执行以下操作:
# do something with my_array[0] or my_array.first
my_array.each do |e|
# do the same general thing to all elements
end
但是,如果您不想对第一个元素做一般性的事情,则可以执行以下操作:
# 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
my_array.drop(1)
它更具声明性。
drop
。好多了。
数组有一个“ each_with_index”方法,在这种情况下很方便:
my_array.each_with_index do |item, i|
item.do_something if i==0
#common stuff
end
最适合的取决于情况。
另一个选择(如果您知道数组不为空):
# treat the first element (my_array.first)
my_array.each do | item |
# do the common_stuff
end
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]
如果之后不需要数组:
ar = %w(reversed hello world)
puts ar.shift.upcase
ar.each{|item| puts item.reverse}
#=>REVERSED
#=>olleh
#=>dlrow
else
某个地方。但这确实可以解决问题的标题。
RubyEnumerable#inject
提供了一个参数,可用于在循环的第一次迭代中执行不同的操作:
> l=[1,2,3,4]
=> [1, 2, 3, 4]
> l.inject(0) {|sum, elem| sum+elem}
=> 10
对于诸如sum和product之类的常见事物,该参数不是严格必需的:
> l.inject {|sum, elem| sum+elem}
=> 10
但是,当你想要做一些不同的在第一次循环,这样的说法可能是对你有用:
> puts fruits.inject("I like to eat: ") {|acc, elem| acc << elem << " "}
I like to eat: apples pears peaches plums oranges
=> nil
inject
我认为它不能回答OP的问题-这是仅在循环的第一次迭代中如何做一些不同的事情。
inject
符合他的要求,但也许您正在看到我们错过的内容。他想通过数组第一次做不同的事情。他i += 1
是一个手动计数器,而不是总和。
inject
而忘记了整个论点在第一次迭代中所做的事情是不同的。谢谢。
这是一个不需要立即封闭的解决方案,并且除非确实需要,否则避免了多次指定状态占位符的冗余。
do_this if ($first_time_only ||= [true]).shift
它的范围与所有者匹配:$first_time_only
在全球范围内一次;@first_time_only
对于实例first_time_only
将是一次,对于当前作用域将是一次。
如果您想要多次,等等,[1,2,3]
如果您需要区分您正在进行的是哪个迭代,或者[1, false, 3, 4]
如果您需要一些怪异的东西,则可以很轻松地输入。