Ruby Language
Arrays
Suche…
Syntax
- a = [] # mit Array-Literal
- a = Array.new # entspricht der Verwendung von Literal
- a = Array.new (5) # erstellt ein Array mit 5 Elementen mit dem Wert nil.
- a = Array.new (5, 0) # erstellt ein Array mit 5 Elementen mit dem Standardwert 0.
#Karte
#map
, bereitgestellt von Enumerable, erstellt ein Array durch Aufrufen eines Blocks für jedes Element und Sammeln der Ergebnisse:
[1, 2, 3].map { |i| i * 3 }
# => [3, 6, 9]
['1', '2', '3', '4', '5'].map { |i| i.to_i }
# => [1, 2, 3, 4, 5]
Das ursprüngliche Array wird nicht geändert. Es wird ein neues Array zurückgegeben, das die transformierten Werte in derselben Reihenfolge wie die Quellwerte enthält. map!
kann verwendet werden, wenn Sie das ursprüngliche Array ändern möchten.
In der map
können Sie die Methode aufrufen oder mit proc alle Elemente im Array verwenden.
# call to_i method on all elements
%w(1 2 3 4 5 6 7 8 9 10).map(&:to_i)
# => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# using proc (lambda) on all elements
%w(1 2 3 4 5 6 7 8 9 10).map(&->(i){ i.to_i * 2})
# => [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
map
ist synonym mit collect
.
Erstellen eines Arrays mit dem Literalkonstruktor []
Arrays können erstellt werden, indem eine Liste von Elementen in eckigen Klammern ( [
und ]
) eingeschlossen wird. Array-Elemente in dieser Notation werden durch Kommas getrennt:
array = [1, 2, 3, 4]
Arrays können beliebige Objekte in beliebiger Kombination ohne Typbeschränkung enthalten:
array = [1, 'b', nil, [3, 4]]
Erstellen Sie ein String-Array
Arrays von Strings können mit der prozentualen String- Syntax von ruby erstellt werden:
array = %w(one two three four)
Dies entspricht funktional der Definition des Arrays als:
array = ['one', 'two', 'three', 'four']
Anstelle von %w()
Sie andere übereinstimmende Begrenzungspaare verwenden: %w{...}
, %w[...]
oder %w<...>
.
Es können auch beliebige nicht alphanumerische Trennzeichen verwendet werden, wie zum Beispiel: %w!...!
, %w#...#
oder %w@...@
.
%W
kann anstelle von %w
, um die String-Interpolation zu integrieren. Folgendes berücksichtigen:
var = 'hello'
%w(#{var}) # => ["\#{var}"]
%W(#{var}) # => ["hello"]
Mehrere Wörter können interpretiert werden, indem das Leerzeichen mit einem \ gekennzeichnet wird.
%w(Colorado California New\ York) # => ["Colorado", "California", "New York"]
Erstellen Sie ein Array von Symbolen
array = %i(one two three four)
Erzeugt das Array [:one, :two, :three, :four]
,: [:one, :two, :three, :four]
,: [:one, :two, :three, :four]
.
Anstelle von %i(...)
können Sie %i{...}
oder %i[...]
oder %i!...!
Wenn Sie die Interpolation verwenden möchten, können Sie dies zusätzlich mit %I
tun.
a = 'hello'
b = 'goodbye'
array_one = %I(#{a} #{b} world)
array_two = %i(#{a} #{b} world)
Erzeugt die Arrays: array_one = [:hello, :goodbye, :world]
array_two = [:"\#{a}", :"\#{b}", :world]
array_one = [:hello, :goodbye, :world]
und array_two = [:"\#{a}", :"\#{b}", :world]
Erstellen Sie ein Array mit Array :: new
Ein leeres Array ( []
) kann mit der Klassenmethode von Array::new
, Array::new
:
Array.new
Übergeben Sie ein numerisches Argument, um die Länge des Arrays festzulegen:
Array.new 3 #=> [nil, nil, nil]
Es gibt zwei Möglichkeiten, ein Array mit Standardwerten zu füllen:
- Übergeben Sie einen unveränderlichen Wert als zweites Argument.
- Übergeben Sie einen Block, der den aktuellen Index abruft und veränderliche Werte generiert.
Array.new 3, :x #=> [:x, :x, :x]
Array.new(3) { |i| i.to_s } #=> ["0", "1", "2"]
a = Array.new 3, "X" # Not recommended.
a[1].replace "C" # a => ["C", "C", "C"]
b = Array.new(3) { "X" } # The recommended way.
b[1].replace "C" # b => ["X", "C", "X"]
Array-Elemente bearbeiten
Elemente hinzufügen:
[1, 2, 3] << 4
# => [1, 2, 3, 4]
[1, 2, 3].push(4)
# => [1, 2, 3, 4]
[1, 2, 3].unshift(4)
# => [4, 1, 2, 3]
[1, 2, 3] << [4, 5]
# => [1, 2, 3, [4, 5]]
Elemente entfernen:
array = [1, 2, 3, 4]
array.pop
# => 4
array
# => [1, 2, 3]
array = [1, 2, 3, 4]
array.shift
# => 1
array
# => [2, 3, 4]
array = [1, 2, 3, 4]
array.delete(1)
# => 1
array
# => [2, 3, 4]
array = [1,2,3,4,5,6]
array.delete_at(2) // delete from index 2
# => 3
array
# => [1,2,4,5,6]
array = [1, 2, 2, 2, 3]
array - [2]
# => [1, 3] # removed all the 2s
array - [2, 3, 4]
# => [1] # the 4 did nothing
Arrays kombinieren:
[1, 2, 3] + [4, 5, 6]
# => [1, 2, 3, 4, 5, 6]
[1, 2, 3].concat([4, 5, 6])
# => [1, 2, 3, 4, 5, 6]
[1, 2, 3, 4, 5, 6] - [2, 3]
# => [1, 4, 5, 6]
[1, 2, 3] | [2, 3, 4]
# => [1, 2, 3, 4]
[1, 2, 3] & [3, 4]
# => [3]
Sie können auch Arrays multiplizieren, z
[1, 2, 3] * 2
# => [1, 2, 3, 1, 2, 3]
Arrays Vereinigung, Kreuzung und Differenz
x = [5, 5, 1, 3]
y = [5, 2, 4, 3]
Union ( |
) enthält Elemente aus beiden Arrays, wobei Duplikate entfernt wurden:
x | y
=> [5, 1, 3, 2, 4]
Die Schnittmenge ( &
) enthält Elemente, die sowohl im ersten als auch im zweiten Array vorhanden sind:
x & y
=> [5, 3]
Der Unterschied ( -
) enthält Elemente, die im ersten Array und nicht im zweiten Array vorhanden sind:
x - y
=> [1]
Filtern von Arrays
Häufig möchten wir nur Elemente eines Arrays bearbeiten, die eine bestimmte Bedingung erfüllen:
Wählen
Gibt Elemente zurück, die einer bestimmten Bedingung entsprechen
array = [1, 2, 3, 4, 5, 6]
array.select { |number| number > 3 } # => [4, 5, 6]
Ablehnen
Gibt Elemente zurück, die keiner bestimmten Bedingung entsprechen
array = [1, 2, 3, 4, 5, 6]
array.reject { |number| number > 3 } # => [1, 2, 3]
Sowohl #select
als auch #reject
geben ein Array zurück, sodass sie verkettet werden können:
array = [1, 2, 3, 4, 5, 6]
array.select { |number| number > 3 }.reject { |number| number < 5 }
# => [5, 6]
Injizieren, reduzieren
Injizieren und Verkleinern sind unterschiedliche Namen für dasselbe. In anderen Sprachen werden diese Funktionen oft Falten genannt (wie foldl oder foldr). Diese Methoden sind für jedes Enumerable-Objekt verfügbar.
Inject akzeptiert eine Funktion mit zwei Argumenten und wendet diese auf alle Elementpaare im Array an.
Für das Array [1, 2, 3]
wir alle zusammen mit dem Startwert Null hinzufügen, indem Sie einen Startwert und einen Block wie folgt angeben:
[1,2,3].reduce(0) {|a,b| a + b} # => 6
Hier übergeben wir der Funktion einen Startwert und einen Block, in dem alle Werte zusammen addiert werden. Der Block wird zuerst mit 0
als a
und 1
als b
, dann wird das Ergebnis als nächstes a
, und wir addieren dann 1
zum zweiten Wert 2
. Dann nehmen wir das Ergebnis von ( 3
) und fügen es dem letzten Element in der Liste (auch 3
) hinzu, wodurch wir unser Ergebnis ( 6
) erhalten.
Wenn wir das erste Argument weglassen, wird a
als erstes Element in der Liste festgelegt. Das obige Beispiel ist also dasselbe:
[1,2,3].reduce {|a,b| a + b} # => 6
Anstatt einen Block mit einer Funktion zu übergeben, können wir eine benannte Funktion als Symbol übergeben, entweder mit einem Startwert oder ohne. Damit könnte das obige Beispiel geschrieben werden als:
[1,2,3].reduce(0, :+) # => 6
oder den Startwert weglassen:
[1,2,3].reduce(:+) # => 6
Zugriff auf Elemente
Sie können über ihre Indizes auf die Elemente eines Arrays zugreifen. Die Nummerierung der Array-Indizes beginnt bei 0
.
%w(a b c)[0] # => 'a'
%w(a b c)[1] # => 'b'
Sie können ein Array mit Bereich beschneiden
%w(a b c d)[1..2] # => ['b', 'c'] (indices from 1 to 2, including the 2)
%w(a b c d)[1...2] # => ['b'] (indices from 1 to 2, excluding the 2)
Dies gibt ein neues Array zurück, wirkt sich aber nicht auf das Original aus. Ruby unterstützt auch die Verwendung negativer Indizes.
%w(a b c)[-1] # => 'c'
%w(a b c)[-2] # => 'b'
Sie können auch negative und positive Indizes kombinieren
%w(a b c d e)[1...-1] # => ['b', 'c', 'd']
Andere nützliche Methoden
Verwenden Sie first
das erste Element in einem Array:
[1, 2, 3, 4].first # => 1
Oder first(n)
auf die ersten n
Elemente zugreifen, die in einem Array zurückgegeben werden:
[1, 2, 3, 4].first(2) # => [1, 2]
Ähnlich für last
und last(n)
:
[1, 2, 3, 4].last # => 4
[1, 2, 3, 4].last(2) # => [3, 4]
Verwenden Sie sample
um auf ein zufälliges Element in einem Array zuzugreifen:
[1, 2, 3, 4].sample # => 3
[1, 2, 3, 4].sample # => 1
Oder sample(n)
:
[1, 2, 3, 4].sample(2) # => [2, 1]
[1, 2, 3, 4].sample(2) # => [3, 4]
Zweidimensionale Anordnung
Mit dem Array::new
Konstruktor können Sie ein Array mit einer bestimmten Größe und einem neuen Array in jedem seiner Slots initialisieren. Die inneren Arrays können auch eine Größe und einen Anfangswert erhalten.
So erstellen Sie beispielsweise ein 3x4-Array von Nullen:
array = Array.new(3) { Array.new(4) { 0 } }
Das oben generierte Array sieht beim Drucken mit p
:
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
Sie können Elemente wie folgt lesen oder schreiben:
x = array[0][1]
array[2][3] = 2
Arrays und der Splat-Operator (*)
Mit dem Operator *
können Variablen und Arrays entpackt werden, sodass sie als einzelne Argumente an eine Methode übergeben werden können.
Dies kann verwendet werden, um ein einzelnes Objekt in ein Array einzuwickeln, wenn es nicht bereits vorhanden ist:
def wrap_in_array(value)
[*value]
end
wrap_in_array(1)
#> [1]
wrap_in_array([1, 2, 3])
#> [1, 2, 3]
wrap_in_array(nil)
#> []
Im obigen Beispiel akzeptiert die Methode wrap_in_array
ein Argument, value
.
Wenn value
ein Array
, werden seine Elemente entpackt und ein neues Array wird erstellt, das diese Elemente enthält.
Wenn value
ein einzelnes Objekt ist, wird ein neues Array erstellt, das dieses einzelne Objekt enthält.
Wenn value
nil
, wird ein leeres Array zurückgegeben.
Der Splat-Operator ist in einigen Fällen besonders praktisch, wenn er in Methoden als Argument verwendet wird. Beispielsweise können nil
, einzelne Werte und Arrays auf konsistente Weise behandelt werden:
def list(*values)
values.each do |value|
# do something with value
puts value
end
end
list(100)
#> 100
list([100, 200])
#> 100
#> 200
list(nil)
# nothing is outputted
Zersetzung
Jedes Array kann schnell zerlegt werden, indem seine Elemente mehreren Variablen zugewiesen werden. Ein einfaches Beispiel:
arr = [1, 2, 3]
# ---
a = arr[0]
b = arr[1]
c = arr[2]
# --- or, the same
a, b, c = arr
Wenn Sie mit dem Splat- Operator ( *
) eine Variable voranstellen , wird ein Array aller Elemente eingefügt , die nicht von anderen Variablen erfasst wurden. Wenn keine übrig sind, wird ein leeres Array zugewiesen. In einer Zuweisung kann nur ein Splat verwendet werden:
a, *b = arr # a = 1; b = [2, 3]
a, *b, c = arr # a = 1; b = [2]; c = 3
a, b, c, *d = arr # a = 1; b = 2; c = 3; d = []
a, *b, *c = arr # SyntaxError: unexpected *
Die Zersetzung ist sicher und wirft niemals Fehler auf. nil
werden zugewiesen, wenn nicht genügend Elemente vorhanden sind, die dem Verhalten des Operators []
, wenn auf einen Index außerhalb der Grenzen zugegriffen wird:
arr[9000] # => nil
a, b, c, d = arr # a = 1; b = 2; c = 3; d = nil
Decomposition versucht, to_ary
implizit für das zugewiesene Objekt to_ary
. Wenn Sie diese Methode in Ihrem Typ implementieren, können Sie sie zerlegen:
class Foo
def to_ary
[1, 2]
end
end
a, b = Foo.new # a = 1; b = 2
Wenn das Objekt, das gerade zerlegt wird, nicht respond_to?
to_ary
wird es als Einzelelement-Array behandelt:
1.respond_to?(:to_ary) # => false
a, b = 1 # a = 1; b = nil
Die Zerlegung kann auch verschachtelt werden, indem anstelle eines anderen Elements ein ()
begrenzter Zerlegungsausdruck verwendet wird:
arr = [1, [2, 3, 4], 5, 6]
a, (b, *c), *d = arr # a = 1; b = 2; c = [3, 4]; d = [5, 6]
# ^^^^^
Dies ist praktisch das Gegenteil von Splat .
Tatsächlich kann jeder Zerlegungsausdruck durch ()
begrenzt werden. Für die erste Stufe ist die Zerlegung jedoch optional.
a, b = [1, 2]
(a, b) = [1, 2] # the same thing
Randfall: Ein einzelner Bezeichner kann nicht als Zerstörungsmuster verwendet werden, sei es äußerlich oder verschachtelt:
(a) = [1] # SyntaxError
a, (b) = [1, [2]] # SyntaxError
Bei der Zuweisung eines Array-Literal zu einem destruktiven Ausdruck kann äußere []
weggelassen werden:
a, b = [1, 2]
a, b = 1, 2 # exactly the same
Dies wird als parallele Zuweisung bezeichnet , verwendet jedoch dieselbe Zerlegung unter der Haube. Dies ist besonders praktisch, um Werte von Variablen auszutauschen, ohne zusätzliche temporäre Variablen zu verwenden:
t = a; a = b; b = t # an obvious way
a, b = b, a # an idiomatic way
(a, b) = [b, a] # ...and how it works
Die Werte werden erfasst, wenn die rechte Seite der Zuweisung erstellt wird. Die Verwendung derselben Variablen als Quelle und Ziel ist daher relativ sicher.
Verwandeln Sie ein mehrdimensionales Array in ein eindimensionales (abgeflachtes) Array
[1, 2, [[3, 4], [5]], 6].flatten # => [1, 2, 3, 4, 5, 6]
Wenn Sie ein mehrdimensionales Array haben und es zu einem einfachen (dh eindimensionalen) Array machen müssen, können Sie die #flatten
Methode verwenden.
Erhalten Sie eindeutige Array-Elemente
Falls Sie ein Array-Element lesen müssen, um Wiederholungen zu vermeiden, verwenden Sie die #uniq
Methode:
a = [1, 1, 2, 3, 4, 4, 5]
a.uniq
#=> [1, 2, 3, 4, 5]
Wenn Sie alle duplizierten Elemente aus einem Array entfernen möchten, können Sie #uniq!
Methode:
a = [1, 1, 2, 3, 4, 4, 5]
a.uniq!
#=> [1, 2, 3, 4, 5]
Während die Ausgabe die gleiche ist, #uniq!
speichert auch das neue Array:
a = [1, 1, 2, 3, 4, 4, 5]
a.uniq
#=> [1, 2, 3, 4, 5]
a
#=> [1, 1, 2, 3, 4, 4, 5]
a = [1, 1, 2, 3, 4, 4, 5]
a.uniq!
#=> [1, 2, 3, 4, 5]
a
#=> [1, 2, 3, 4, 5]
Holen Sie sich alle Kombinationen / Permutationen eines Arrays
Wenn die permutation
mit einem Block aufgerufen wird, ergibt sich ein zweidimensionales Array, das aus allen geordneten Folgen einer Sammlung von Zahlen besteht.
Wenn diese Methode ohne einen Block aufgerufen wird, wird ein enumerator
. Rufen to_a
zum Konvertieren in ein Array die to_a
Methode auf.
Beispiel | Ergebnis |
---|---|
[1,2,3].permutation | #<Enumerator: [1,2,3]:permutation |
[1,2,3].permutation.to_a | [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] |
[1,2,3].permutation(2).to_a | [[1,2],[1,3],[2,1],[2,3],[3,1],[3,2]] |
[1,2,3].permutation(4).to_a | [] -> Keine Permutationen der Länge 4 |
Die combination
dagegen ergibt bei Aufruf mit einem Block ein zweidimensionales Array, das aus allen Folgen einer Zahlenkollektion besteht. Im Gegensatz zur Permutation wird die Reihenfolge bei Kombinationen nicht berücksichtigt. Zum Beispiel ist [1,2,3]
dasselbe wie [3,2,1]
Beispiel | Ergebnis |
---|---|
[1,2,3].combination(1) | #<Enumerator: [1,2,3]:combination |
[1,2,3].combination(1).to_a | [[1],[2],[3]] |
[1,2,3].combination(3).to_a | [[1,2,3]] |
[1,2,3].combination(4).to_a | [] -> Keine Längenkombinationen 4 |
Ein Aufruf der Kombinationsmethode allein führt zu einem Enumerator. Um ein Array zu erhalten, rufen Sie die to_a
Methode auf.
Die Methoden repeated_combination
und repeat_permutation sind ähnlich, nur dass dasselbe Element repeated_combination
repeated_permutation
werden kann.
Zum Beispiel wären die Sequenzen [1,1]
, [1,3,3,1]
, [3,3,3]
in regulären Kombinationen und Permutationen nicht gültig.
Beispiel | # Combos |
---|---|
[1,2,3].combination(3).to_a.length | 1 |
[1,2,3].repeated_combination(3).to_a.length | 6 |
[1,2,3,4,5].combination(5).to_a.length | 1 |
[1,2,3].repeated_combination(5).to_a.length | 126 |
Erstellen Sie ein Array aus aufeinander folgenden Zahlen oder Buchstaben
Dies kann leicht durch Aufrufen von Enumerable#to_a
für ein Range
Objekt erreicht werden:
(1..10).to_a #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
(a..b)
bedeutet, dass alle Zahlen zwischen a und b eingeschlossen werden. Um die letzte Zahl auszuschließen, verwenden Sie a...b
a_range = 1...5
a_range.to_a #=> [1, 2, 3, 4]
oder
('a'..'f').to_a #=> ["a", "b", "c", "d", "e", "f"]
('a'...'f').to_a #=> ["a", "b", "c", "d", "e"]
Eine praktische Verknüpfung zum Erstellen eines Arrays ist [*a..b]
[*1..10] #=> [1,2,3,4,5,6,7,8,9,10]
[*'a'..'f'] #=> ["a", "b", "c", "d", "e", "f"]
Entfernen Sie alle nil-Elemente mit #compact aus einem Array
Wenn ein Array aus einem oder mehreren nil
Elementen besteht und diese entfernt werden müssen, ist das Array#compact
oder Array#compact!
Methoden können wie folgt verwendet werden.
array = [ 1, nil, 'hello', nil, '5', 33]
array.compact # => [ 1, 'hello', '5', 33]
#notice that the method returns a new copy of the array with nil removed,
#without affecting the original
array = [ 1, nil, 'hello', nil, '5', 33]
#If you need the original array modified, you can either reassign it
array = array.compact # => [ 1, 'hello', '5', 33]
array = [ 1, 'hello', '5', 33]
#Or you can use the much more elegant 'bang' version of the method
array = [ 1, nil, 'hello', nil, '5', 33]
array.compact # => [ 1, 'hello', '5', 33]
array = [ 1, 'hello', '5', 33]
#compact!
schließlich, dass #compact
oder #compact!
Wird für ein Array ohne nil
Elemente aufgerufen, geben diese null zurück.
array = [ 'foo', 4, 'life']
array.compact # => nil
array.compact! # => nil
Erstellen Sie ein Array von Zahlen
Die normale Art, ein Zahlenfeld zu erstellen:
numbers = [1, 2, 3, 4, 5]
Bereichsobjekte können umfangreich verwendet werden, um ein Zahlenfeld zu erstellen:
numbers = Array(1..10) # => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
numbers = (1..10).to_a # => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
#step
Methoden #step
und #map
ermöglichen es uns, Bedingungen für den Zahlenbereich #map
:
odd_numbers = (1..10).step(2).to_a # => [1, 3, 5, 7, 9]
even_numbers = 2.step(10, 2).to_a # => [2, 4, 6, 8, 10]
squared_numbers = (1..10).map { |number| number * number } # => [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
Alle oben genannten Methoden laden die Zahlen eifrig auf. Wenn Sie sie faul laden müssen:
number_generator = (1..100).lazy # => #<Enumerator::Lazy: 1..100>
number_generator.first(10) # => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Umwandlung von beliebigen Objekten in ein Array
Um ein Array von einem Objekt zu erhalten, verwenden Sie das Kernel#Array
.
Das folgende ist ein Beispiel:
Array('something') #=> ["something"]
Array([2, 1, 5]) #=> [2, 1, 5]
Array(1) #=> [1]
Array(2..4) #=> [2, 3, 4]
Array([]) #=> []
Array(nil) #=> []
Beispielsweise könnten Sie die join_as_string
Methode aus dem folgenden Code ersetzen
def join_as_string(arg)
if arg.instance_of?(Array)
arg.join(',')
elsif arg.instance_of?(Range)
arg.to_a.join(',')
else
arg.to_s
end
end
join_as_string('something') #=> "something"
join_as_string([2, 1, 5]) #=> "2,1,5"
join_as_string(1) #=> "1"
join_as_string(2..4) #=> "2,3,4"
join_as_string([]) #=> ""
join_as_string(nil) #=> ""
zum folgenden Code.
def join_as_string(arg)
Array(arg).join(',')
end