Ich benutze immer einen Zähler, um nach dem ersten item ( i==0
) in einer Schleife zu suchen:
i = 0
my_array.each do |item|
if i==0
# do something with the first item
end
# common stuff
i += 1
end
Gibt es eine elegantere Möglichkeit, dies zu tun (vielleicht eine Methode)?
each
Schleife mit nur den üblichen Dingen durchzuführen?array.first
oderarray[0]
) und dann dieeach
Schleife ausführt , muss er immer noch auf den ersten Gegenstand testen, wenn er nicht auch das reguläre Ding mit dem ersten Gegenstand machen möchte.my_array[1..-1].each
?Antworten:
Du kannst das:
my_array.each_with_index do |item, index| if index == 0 # do something with the first item end # common stuff end
Probieren Sie es auf ideone .
quelle
.each_with_index
anstelle von.each
. Der folgende.drop(1)
Vorschlag wirkt eher rubinrot und vermeidet Indizes insgesamt.if index > 1
und den Fehler bekommenundefined method '>' for nil:NilClass
Die Verwendung
each_with_index
, wie andere beschrieben haben, würde gut funktionieren, aber aus Gründen der Abwechslung ist hier ein anderer Ansatz.Wenn Sie etwas Spezifisches nur für das erste Element und etwas Allgemeines für alle Elemente einschließlich des ersten tun möchten, können Sie Folgendes tun:
# do something with my_array[0] or my_array.first my_array.each do |e| # do the same general thing to all elements end
Aber wenn Sie das Allgemeine mit dem ersten Element nicht tun möchten, können Sie Folgendes tun:
# 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
quelle
my_array.drop(1)
es ist deklarativer.drop
. Es ist viel schöner.Arrays haben eine "each_with_index" -Methode, die für diese Situation praktisch ist:
my_array.each_with_index do |item, i| item.do_something if i==0 #common stuff end
quelle
Was am besten passt, hängt von der jeweiligen Situation ab.
Eine weitere Option (wenn Sie wissen, dass Ihr Array nicht leer ist):
# treat the first element (my_array.first) my_array.each do | item | # do the common_stuff end
quelle
each_with_index
von Enumerable (Enumerable ist bereits mit Array gemischt, sodass Sie es problemlos auf einem Array aufrufen können):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]
quelle
Wenn Sie das Array danach nicht benötigen:
ar = %w(reversed hello world) puts ar.shift.upcase ar.each{|item| puts item.reverse} #=>REVERSED #=>olleh #=>dlrow
quelle
else
irgendwo etwas vorgestellt haben. Aber es macht das, was der Titel der Frage sagt.Ruby's
Enumerable#inject
bietet ein Argument, mit dem Sie bei der ersten Iteration einer Schleife etwas anderes tun können:> l=[1,2,3,4] => [1, 2, 3, 4] > l.inject(0) {|sum, elem| sum+elem} => 10
Das Argument ist für gängige Dinge wie Summen und Produkte nicht unbedingt erforderlich:
> l.inject {|sum, elem| sum+elem} => 10
Wenn Sie jedoch bei der ersten Iteration etwas anderes tun möchten , kann dieses Argument für Sie hilfreich sein:
> puts fruits.inject("I like to eat: ") {|acc, elem| acc << elem << " "} I like to eat: apples pears peaches plums oranges => nil
quelle
inject
ich glaube, es beantwortet nicht die Frage des OP - wie man etwas anderes nur für die erste Iteration der Schleife macht.inject
passe nicht zu dem, wonach er fragt, aber vielleicht sehen Sie etwas, das wir verpasst haben. Er möchte beim ersten Mal etwas anderes durch ein Array machen. Seini += 1
ist ein manueller Zähler, keine Summe.inject
und vergaß, dass der springende Punkt des Arguments bei der ersten Iteration etwas anderes war. Vielen Dank.Hier ist eine Lösung, die sich nicht in einer sofort einschließenden Schleife befinden muss und die Redundanz vermeidet, einen Statusplatzhalter mehrmals anzugeben, es sei denn, Sie müssen dies wirklich tun.
do_this if ($first_time_only ||= [true]).shift
Sein Umfang entspricht dem Inhaber:
$first_time_only
wird global einmal sein;@first_time_only
wird einmal für die Instanz undfirst_time_only
einmal für den aktuellen Bereich sein.Wenn Sie die ersten mehrmals möchten, können Sie leicht sagen,
[1,2,3]
ob Sie unterscheiden müssen, in welcher der ersten Iterationen Sie sich befinden, oder sogar etwas Besonderes,[1, false, 3, 4]
wenn Sie etwas Seltsames benötigen.quelle