Ruby Language
arrays
Zoeken…
Syntaxis
- a = [] # met letterlijk array
- a = Array.new # gelijk aan het gebruik van letterlijk
- a = Array.new (5) # maak een array met 5 elementen met de waarde nul.
- a = Array.new (5, 0) # maak een array met 5 elementen met standaardwaarde 0.
#kaart
#map
, aangeboden door Enumerable, maakt een array door een blok voor elk element aan te roepen en de resultaten te verzamelen:
[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]
De oorspronkelijke array is niet gewijzigd; er wordt een nieuwe array geretourneerd met de getransformeerde waarden in dezelfde volgorde als de bronwaarden. map!
kan worden gebruikt als u de oorspronkelijke array wilt wijzigen.
In map
methode kunt u methode of het gebruik proc bellen om alle elementen in de array.
# 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
is synoniem met collect
.
Een array maken met de letterlijke constructor []
Arrays kunnen worden gemaakt door een lijst met elementen tussen vierkante haken ( [
en ]
) te plaatsen. Matrixelementen in deze notatie worden gescheiden door komma's:
array = [1, 2, 3, 4]
Arrays kunnen elk soort objecten in elke combinatie bevatten zonder beperkingen op het type:
array = [1, 'b', nil, [3, 4]]
Maak een reeks strings
Arrays van strings kunnen worden gemaakt met behulp van Ruby's percentagesyntaxis :
array = %w(one two three four)
Dit komt functioneel overeen met het definiëren van de array als:
array = ['one', 'two', 'three', 'four']
In plaats van %w()
kunt u andere overeenkomende scheidingstekens gebruiken: %w{...}
, %w[...]
of %w<...>
.
Het is ook mogelijk om willekeurige niet-alfanumerieke scheidingstekens te gebruiken, zoals: %w!...!
, %w#...#
of %w@...@
.
%W
kan worden gebruikt in plaats van %w
om stringinterpolatie op te nemen. Stel je de volgende situatie voor:
var = 'hello'
%w(#{var}) # => ["\#{var}"]
%W(#{var}) # => ["hello"]
Meerdere woorden kunnen worden geïnterpreteerd door met een \ aan de spatie te ontsnappen.
%w(Colorado California New\ York) # => ["Colorado", "California", "New York"]
Maak een reeks symbolen
array = %i(one two three four)
Creëert de array [:one, :two, :three, :four]
,: [:one, :two, :three, :four]
.
In plaats van %i(...)
kunt u %i{...}
of %i[...]
of %i!...!
Als u interpolatie wilt gebruiken, kunt u dit bovendien doen met %I
a = 'hello'
b = 'goodbye'
array_one = %I(#{a} #{b} world)
array_two = %i(#{a} #{b} world)
Maakt de arrays: array_one = [:hello, :goodbye, :world]
array_two = [:"\#{a}", :"\#{b}", :world]
array_one = [:hello, :goodbye, :world]
en array_two = [:"\#{a}", :"\#{b}", :world]
Maak Array met Array :: nieuw
Een lege matrix ( []
) kan worden gemaakt met de klassemethode Array::new
:
Array.new
Voer een numeriek argument in om de lengte van de array in te stellen:
Array.new 3 #=> [nil, nil, nil]
Er zijn twee manieren om een array met standaardwaarden te vullen:
- Geef een onveranderlijke waarde door als tweede argument.
- Passeer een blok dat de huidige index krijgt en veranderbare waarden genereert.
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"]
Matrixelementen manipuleren
Elementen toevoegen:
[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]]
Elementen verwijderen:
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 combineren:
[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]
U kunt ook arrays vermenigvuldigen, bijvoorbeeld
[1, 2, 3] * 2
# => [1, 2, 3, 1, 2, 3]
Arrays unie, kruising en verschil
x = [5, 5, 1, 3]
y = [5, 2, 4, 3]
Union ( |
) bevat elementen uit beide arrays, zonder duplicaten:
x | y
=> [5, 1, 3, 2, 4]
Kruising ( &
) bevat elementen die zowel in de eerste als in de tweede reeks aanwezig zijn:
x & y
=> [5, 3]
Verschil ( -
) bevat elementen die aanwezig zijn in de eerste array en niet aanwezig zijn in de tweede array:
x - y
=> [1]
Arrays filteren
Vaak willen we alleen werken op elementen van een array die aan een specifieke voorwaarde voldoen:
kiezen
Retourneert elementen die overeenkomen met een specifieke voorwaarde
array = [1, 2, 3, 4, 5, 6]
array.select { |number| number > 3 } # => [4, 5, 6]
afwijzen
Retourneert elementen die niet overeenkomen met een specifieke voorwaarde
array = [1, 2, 3, 4, 5, 6]
array.reject { |number| number > 3 } # => [1, 2, 3]
Zowel #select
als #reject
retourneren een array, zodat ze kunnen worden gekoppeld:
array = [1, 2, 3, 4, 5, 6]
array.select { |number| number > 3 }.reject { |number| number < 5 }
# => [5, 6]
Injecteren, verminderen
Injecteren en verkleinen zijn verschillende namen voor hetzelfde. In andere talen worden deze functies vaak vouwen genoemd (zoals foldl of foldr). Deze methoden zijn beschikbaar voor elk Enumerable-object.
Inject neemt een functie met twee argumenten aan en past die toe op alle paren elementen in de array.
Voor de array [1, 2, 3]
we deze allemaal samen met de startwaarde nul toevoegen door een startwaarde op te geven en zo te blokkeren:
[1,2,3].reduce(0) {|a,b| a + b} # => 6
Hier geven we de functie een startwaarde en een blok dat zegt dat alle waarden bij elkaar moeten worden opgeteld. Het blok wordt eerst uitgevoerd met 0
als a
en 1
als b
en neemt het resultaat daarvan als de volgende a
dus we voegen dan 1
aan de tweede waarde 2
. Vervolgens nemen we het resultaat van dat ( 3
) en voegen dat toe aan het laatste element in de lijst (ook 3
) en geven ons ons resultaat ( 6
).
Als we het eerste argument weglaat, zal het instellen a
het feit dat het eerste element in de lijst, dus het bovenstaande voorbeeld is hetzelfde als:
[1,2,3].reduce {|a,b| a + b} # => 6
Bovendien kunnen we in plaats van een blok met een functie door te geven, een benoemde functie als een symbool doorgeven, hetzij met een startwaarde, hetzij zonder. Hiermee zou het bovenstaande voorbeeld kunnen worden geschreven als:
[1,2,3].reduce(0, :+) # => 6
of het weglaten van de startwaarde:
[1,2,3].reduce(:+) # => 6
Toegang tot elementen
U hebt toegang tot de elementen van een array met hun indices. Nummering van de array-index begint bij 0
.
%w(a b c)[0] # => 'a'
%w(a b c)[1] # => 'b'
U kunt een array bijsnijden met behulp van het bereik
%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)
Dit retourneert een nieuwe array, maar heeft geen invloed op het origineel. Ruby ondersteunt ook het gebruik van negatieve indices.
%w(a b c)[-1] # => 'c'
%w(a b c)[-2] # => 'b'
U kunt ook negatieve en positieve indices combineren
%w(a b c d e)[1...-1] # => ['b', 'c', 'd']
Andere bruikbare methoden
Gebruik first
om toegang te krijgen tot het eerste element in een array:
[1, 2, 3, 4].first # => 1
Of first(n)
om toegang te krijgen tot de eerste n
elementen die in een array worden geretourneerd:
[1, 2, 3, 4].first(2) # => [1, 2]
Evenzo voor de last
en last(n)
:
[1, 2, 3, 4].last # => 4
[1, 2, 3, 4].last(2) # => [3, 4]
Gebruik een sample
om toegang te krijgen tot een willekeurig element in een array:
[1, 2, 3, 4].sample # => 3
[1, 2, 3, 4].sample # => 1
Of sample(n)
:
[1, 2, 3, 4].sample(2) # => [2, 1]
[1, 2, 3, 4].sample(2) # => [3, 4]
Tweedimensionale reeks
Met de Array::new
constructor kunt u een array met een bepaalde grootte en een nieuwe array in elk van zijn slots initialiseren. De binnenste reeksen kunnen ook een grootte en een beginwaarde krijgen.
Om bijvoorbeeld een 3x4 array van nullen te maken:
array = Array.new(3) { Array.new(4) { 0 } }
De hierboven gegenereerde array ziet er zo uit wanneer deze wordt afgedrukt met p
:
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
U kunt elementen zoals deze lezen of schrijven:
x = array[0][1]
array[2][3] = 2
Arrays en de operator splat (*)
De operator *
kan worden gebruikt om variabelen en arrays uit te pakken zodat ze als individuele argumenten aan een methode kunnen worden doorgegeven.
Dit kan worden gebruikt om een enkel object in een array te wikkelen als dit nog niet is:
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)
#> []
In het bovenstaande voorbeeld accepteert de methode wrap_in_array
één argument, value
.
Als value
een Array
, worden de elementen uitgepakt en wordt een nieuwe array gemaakt met dat element.
Als value
een enkel object is, wordt een nieuwe array gemaakt met dat enkele object.
Als de value
nil
, wordt een lege array geretourneerd.
De splat-operator is met name handig wanneer deze in sommige gevallen als argument wordt gebruikt in methoden. Hiermee kunnen bijvoorbeeld nil
, enkele waarden en arrays op een consistente manier worden verwerkt:
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
Ontleding
Elke array kan snel worden ontleed door de elementen toe te wijzen in meerdere variabelen. Een eenvoudig voorbeeld:
arr = [1, 2, 3]
# ---
a = arr[0]
b = arr[1]
c = arr[2]
# --- or, the same
a, b, c = arr
Voorafgaand aan een variabele met de splat- operator ( *
) wordt er een array van alle elementen in opgenomen die niet door andere variabelen zijn vastgelegd. Als er niets over is, wordt een lege array toegewezen. Er kan slechts één splat in een enkele opdracht worden gebruikt:
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 *
Ontleding is veilig en geeft nooit fouten. nil
worden toegewezen wanneer er niet genoeg elementen zijn, die overeenkomen met het gedrag van de operator []
bij het openen van een index buiten de grenzen:
arr[9000] # => nil
a, b, c, d = arr # a = 1; b = 2; c = 3; d = nil
Decompositie probeert impliciet to_ary
aan te roepen op het object dat wordt toegewezen. Door deze methode in uw type te implementeren, krijgt u de mogelijkheid om het te ontleden:
class Foo
def to_ary
[1, 2]
end
end
a, b = Foo.new # a = 1; b = 2
Als het te ontbinden object niet respond_to?
to_ary
, het wordt behandeld als een array met één element:
1.respond_to?(:to_ary) # => false
a, b = 1 # a = 1; b = nil
Decompositie kan ook worden genest door een ()
-gescheiden decompositie-expressie te gebruiken in plaats van wat anders een enkel element zou zijn:
arr = [1, [2, 3, 4], 5, 6]
a, (b, *c), *d = arr # a = 1; b = 2; c = [3, 4]; d = [5, 6]
# ^^^^^
Dit is eigenlijk het tegenovergestelde van splat .
Eigenlijk kan elke ontledingsuitdrukking worden gescheiden door ()
. Maar voor het eerste niveau is ontleding optioneel.
a, b = [1, 2]
(a, b) = [1, 2] # the same thing
Randgeval: een enkele identificatie kan niet worden gebruikt als een destructief patroon, of het nu buitenste of een geneste is:
(a) = [1] # SyntaxError
a, (b) = [1, [2]] # SyntaxError
Wanneer een letterlijke array wordt toegewezen aan een destructurerende uitdrukking, kan outer []
worden weggelaten:
a, b = [1, 2]
a, b = 1, 2 # exactly the same
Dit staat bekend als parallelle toewijzing , maar het gebruikt dezelfde ontleding onder de motorkap. Dit is vooral handig voor het uitwisselen van de waarden van variabelen zonder extra tijdelijke variabelen te gebruiken:
t = a; a = b; b = t # an obvious way
a, b = b, a # an idiomatic way
(a, b) = [b, a] # ...and how it works
Waarden worden vastgelegd bij het bouwen van de rechterkant van de toewijzing, dus het gebruik van dezelfde variabelen als bron en bestemming is relatief veilig.
Verander een multidimensionale array in een eendimensionale (afgeplatte) array
[1, 2, [[3, 4], [5]], 6].flatten # => [1, 2, 3, 4, 5, 6]
Als u een multidimensionale array hebt en er een eenvoudige (dwz eendimensionale) array van moet maken, kunt u de #flatten
methode gebruiken.
Ontvang unieke array-elementen
Als u matrixelementen moet lezen om herhalingen te voorkomen , gebruikt u de #uniq
methode:
a = [1, 1, 2, 3, 4, 4, 5]
a.uniq
#=> [1, 2, 3, 4, 5]
Als u in plaats daarvan alle gedupliceerde elementen uit een array wilt verwijderen, kunt u #uniq!
methode:
a = [1, 1, 2, 3, 4, 4, 5]
a.uniq!
#=> [1, 2, 3, 4, 5]
Hoewel de uitvoer hetzelfde is, #uniq!
slaat ook de nieuwe array op:
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]
Verkrijg alle combinaties / permutaties van een array
De permutation
levert, wanneer deze met een blok wordt aangeroepen, een tweedimensionale array op die bestaat uit alle geordende reeksen van een verzameling getallen.
Als deze methode zonder een blok wordt aangeroepen, retourneert deze een enumerator
. to_a
methode to_a
aan om naar een array te converteren.
Voorbeeld | Resultaat |
---|---|
[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 | [] -> Geen permutaties van lengte 4 |
De combination
daarentegen levert, wanneer deze met een blok wordt aangeroepen, een tweedimensionale array op die bestaat uit alle reeksen van een verzameling getallen. In tegenstelling tot permutatie wordt volgorde in combinaties genegeerd. [1,2,3]
is bijvoorbeeld hetzelfde als [3,2,1]
Voorbeeld | Resultaat |
---|---|
[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 | [] -> Geen combinaties van lengte 4 |
Als u alleen de combinatiemethode aanroept, krijgt u een teller. to_a
methode to_a
aan om een array te krijgen.
De repeated_combination
en repeated_permutation
methoden zijn vergelijkbaar, behalve dat hetzelfde element meerdere keren kan worden herhaald.
De sequenties [1,1]
, [1,3,3,1]
, [3,3,3]
zouden bijvoorbeeld niet geldig zijn in reguliere combinaties en permutaties.
Voorbeeld | # Combo's |
---|---|
[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 |
Maak een matrix van opeenvolgende cijfers of letters
Dit kan eenvoudig worden bereikt door Enumerable#to_a
aan te Enumerable#to_a
op een Range
object:
(1..10).to_a #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
(a..b)
betekent dat het alle getallen tussen a en b zal bevatten. Gebruik a...b
om het laatste nummer uit te sluiten
a_range = 1...5
a_range.to_a #=> [1, 2, 3, 4]
of
('a'..'f').to_a #=> ["a", "b", "c", "d", "e", "f"]
('a'...'f').to_a #=> ["a", "b", "c", "d", "e"]
Een handige sneltoets voor het maken van een array is [*a..b]
[*1..10] #=> [1,2,3,4,5,6,7,8,9,10]
[*'a'..'f'] #=> ["a", "b", "c", "d", "e", "f"]
Verwijder alle nulelementen uit een array met #compact
Als een array toevallig een of meer nil
en deze moeten worden verwijderd, wordt de Array#compact
of Array#compact!
methoden kunnen worden gebruikt, zoals hieronder.
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]
Merk ten slotte op dat als #compact
of #compact!
worden aangeroepen op een array zonder nil
elementen, deze zullen nul teruggeven.
array = [ 'foo', 4, 'life']
array.compact # => nil
array.compact! # => nil
Maak een reeks getallen
De normale manier om een reeks getallen te maken:
numbers = [1, 2, 3, 4, 5]
Bereikobjecten kunnen uitgebreid worden gebruikt om een reeks getallen te maken:
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
en #map
kunnen voorwaarden worden gesteld aan de reeks getallen:
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 bovenstaande methoden laden de nummers gretig. Als je ze lui moet laden:
number_generator = (1..100).lazy # => #<Enumerator::Lazy: 1..100>
number_generator.first(10) # => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Cast naar Array vanuit elk object
Gebruik Kernel#Array
om Array van een willekeurig object te krijgen.
Het volgende is een voorbeeld:
Array('something') #=> ["something"]
Array([2, 1, 5]) #=> [2, 1, 5]
Array(1) #=> [1]
Array(2..4) #=> [2, 3, 4]
Array([]) #=> []
Array(nil) #=> []
U kunt bijvoorbeeld de methode join_as_string
vervangen door de volgende code
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) #=> ""
naar de volgende code.
def join_as_string(arg)
Array(arg).join(',')
end