Ruby Language
arrayer
Sök…
Syntax
- a = [] # med hjälp av array letteral
- a = Array.new # motsvarande att använda bokstavlig
- a = Array.new (5) # skapa en matris med 5 element med värdet noll.
- a = Array.new (5, 0) # skapa en matris med 5 element med standardvärdet 0.
#Karta
#map
, tillhandahålls av Enumerable, skapar en matris genom att åberopa ett block på varje element och samla resultaten:
[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]
Den ursprungliga matrisen är inte modifierad; en ny matris returneras som innehåller de transformerade värdena i samma ordning som källvärdena. map!
kan användas om du vill ändra den ursprungliga matrisen.
I map
metod kan du ringa metod eller användning proc till alla element i arrayen.
# 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
är synonymt med collect
.
Skapa en matris med den bokstavliga konstruktören []
Matriser kan skapas genom att lägga till en lista över element i fyrkantiga parenteser ( [
och ]
). Arrayelement i denna notation separeras med komma:
array = [1, 2, 3, 4]
Arrays kan innehålla alla typer av objekt i valfri kombination utan begränsningar för typ:
array = [1, 'b', nil, [3, 4]]
Skapa array av strängar
Matriser av strängar kan skapas med Rubys procentsträngsyntax :
array = %w(one two three four)
Detta är funktionellt ekvivalent med att definiera matrisen som:
array = ['one', 'two', 'three', 'four']
I stället för %w()
kan du använda andra matchande par avgränsare: %w{...}
, %w[...]
eller %w<...>
.
Det är också möjligt att använda godtyckliga icke-alfanumeriska avgränsare, till exempel: %w!...!
, %w#...#
eller %w@...@
.
%W
kan användas istället för %w
att införliva stränginterpolering. Tänk på följande:
var = 'hello'
%w(#{var}) # => ["\#{var}"]
%W(#{var}) # => ["hello"]
Flera ord kan tolkas genom att undgå rymden med en \.
%w(Colorado California New\ York) # => ["Colorado", "California", "New York"]
Skapa array av symboler
array = %i(one two three four)
Skapar matrisen [:one, :two, :three, :four]
.
Istället för %i(...)
kan du använda %i{...}
eller %i[...]
eller %i!...!
Om du vill använda interpolering kan du dessutom göra detta med %I
a = 'hello'
b = 'goodbye'
array_one = %I(#{a} #{b} world)
array_two = %i(#{a} #{b} world)
Skapar matriserna: array_one = [:hello, :goodbye, :world]
array_two = [:"\#{a}", :"\#{b}", :world]
array_one = [:hello, :goodbye, :world]
och array_two = [:"\#{a}", :"\#{b}", :world]
Skapa Array med Array :: nytt
En tom Array ( []
) kan skapas med Arrays klassmetod, Array::new
:
Array.new
För att ställa in längden på arrayen, passera ett numeriskt argument:
Array.new 3 #=> [nil, nil, nil]
Det finns två sätt att fylla i en matris med standardvärden:
- Ge ett immutable värde som andra argument.
- Passera ett block som får aktuellt index och genererar muterbara värden.
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"]
Manipulera arrayelement
Lägga till element:
[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]]
Ta bort element:
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
Kombinera matriser:
[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]
Du kan också multiplicera matriser, t.ex.
[1, 2, 3] * 2
# => [1, 2, 3, 1, 2, 3]
Arrays union, skärningspunkt och skillnad
x = [5, 5, 1, 3]
y = [5, 2, 4, 3]
Union ( |
) innehåller element från båda matriserna, med dubbletter borttagna:
x | y
=> [5, 1, 3, 2, 4]
Korsning ( &
) innehåller element som finns både i första och andra array:
x & y
=> [5, 3]
Skillnad ( -
) innehåller element som finns i första matrisen och inte finns i andra array:
x - y
=> [1]
Filtrera matriser
Ofta vill vi bara arbeta med element i en matris som uppfyller ett specifikt villkor:
Välj
Kommer att returnera element som matchar ett specifikt villkor
array = [1, 2, 3, 4, 5, 6]
array.select { |number| number > 3 } # => [4, 5, 6]
Avvisa
Kommer att returnera element som inte matchar ett specifikt villkor
array = [1, 2, 3, 4, 5, 6]
array.reject { |number| number > 3 } # => [1, 2, 3]
Både #select
och #reject
returnerar en matris, så att de kan kedjas:
array = [1, 2, 3, 4, 5, 6]
array.select { |number| number > 3 }.reject { |number| number < 5 }
# => [5, 6]
Injicera, minska
Injicera och minska är olika namn på samma sak. På andra språk kallas dessa funktioner ofta mappar (som foldl eller foldr). Dessa metoder finns tillgängliga på alla Otaliga objekt.
Inject tar en tvåargumentfunktion och tillämpar den på alla elementpar i Array.
För matrisen [1, 2, 3]
vi lägga till alla dessa tillsammans med startvärdet noll genom att ange ett startvärde och blockera så:
[1,2,3].reduce(0) {|a,b| a + b} # => 6
Här passerar vi funktionen ett startvärde och ett block som säger att lägga till alla värden tillsammans. Blocket körs först med 0
som a
och 1
som b
och tar sedan resultatet av det som nästa a
så vi lägger sedan till 1
till det andra värdet 2
. Sedan tar vi resultatet av det ( 3
) och lägger till det till det sista elementet i listan (också 3
) som ger oss vårt resultat ( 6
).
Om vi utelämnar det första argumentet, kommer det att ställa a
till att vara det första elementet i listan, så exemplet ovan är samma som:
[1,2,3].reduce {|a,b| a + b} # => 6
I stället för att passera ett block med en funktion kan vi passera en namngivna funktion som en symbol, antingen med ett startvärde, eller utan. Med detta kan exemplet ovan skrivas som:
[1,2,3].reduce(0, :+) # => 6
eller utelämna startvärdet:
[1,2,3].reduce(:+) # => 6
Åtkomst till element
Du kan komma åt elementen i en matris med deras index. Arrayindexnumrering börjar vid 0
.
%w(a b c)[0] # => 'a'
%w(a b c)[1] # => 'b'
Du kan beskära en matris med intervall
%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)
Detta returnerar en ny matris, men påverkar inte originalet. Ruby stöder också användningen av negativa index.
%w(a b c)[-1] # => 'c'
%w(a b c)[-2] # => 'b'
Du kan också kombinera negativa och positiva index
%w(a b c d e)[1...-1] # => ['b', 'c', 'd']
Andra användbara metoder
Använd first
att komma åt det första elementet i en matris:
[1, 2, 3, 4].first # => 1
Eller first(n)
att komma åt de första n
elementen som returneras i en matris:
[1, 2, 3, 4].first(2) # => [1, 2]
På samma sätt för last
och last(n)
:
[1, 2, 3, 4].last # => 4
[1, 2, 3, 4].last(2) # => [3, 4]
Använd sample
att komma åt ett slumpmässigt element i en matris:
[1, 2, 3, 4].sample # => 3
[1, 2, 3, 4].sample # => 1
Eller sample(n)
:
[1, 2, 3, 4].sample(2) # => [2, 1]
[1, 2, 3, 4].sample(2) # => [3, 4]
Två-dimensionell matris
Med Array::new
konstruktör kan du initiera en matris med en given storlek och en ny matris i var och en av dess fack. De inre matriserna kan också ges en storlek och ett initialt värde.
Till exempel för att skapa en 3x4 matris med nollor:
array = Array.new(3) { Array.new(4) { 0 } }
Arrayen som genereras ovan ser ut så här när den skrivs ut med p
:
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
Du kan läsa eller skriva till sådana element:
x = array[0][1]
array[2][3] = 2
Arrays och operatören splat (*)
Operatören *
kan användas för att packa upp variabler och arrayer så att de kan skickas som enskilda argument till en metod.
Detta kan användas för att linda in ett enda objekt i en array om det inte redan är:
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)
#> []
I exemplet wrap_in_array
accepterar metoden wrap_in_array
ett argument, value
.
Om value
är en Array
, packas dess element upp och en ny matris skapas som innehåller dessa element.
Om value
är ett enda objekt skapas en ny matris som innehåller det enda objektet.
Om value
är nil
returneras en tom matris.
Splatsoperatören är särskilt praktisk när den används som argument i metoder i vissa fall. Till exempel tillåter det att nil
, enskilda värden och matriser hanteras på ett konsekvent sätt:
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
Sönderfall
Varje matris kan snabbt sönderdelas genom att tilldela dess element i flera variabler. Ett enkelt exempel:
arr = [1, 2, 3]
# ---
a = arr[0]
b = arr[1]
c = arr[2]
# --- or, the same
a, b, c = arr
Före en variabel med splatoperatören ( *
) läggs i den en matris med alla element som inte har fångats in av andra variabler. Om ingen finns kvar tilldelas tom matris. Endast en splat kan användas i en enda tilldelning:
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 *
Nedbrytning är säker och väcker aldrig fel. nil
tilldelas där det inte finns tillräckligt med element, som matchar beteendet hos []
operatören när ett index kommer utanför gränserna:
arr[9000] # => nil
a, b, c, d = arr # a = 1; b = 2; c = 3; d = nil
Nedbrytning försöker ringa to_ary
implicit på objektet tilldelas. Genom att implementera den här metoden i din typ får du förmågan att sönderdela den:
class Foo
def to_ary
[1, 2]
end
end
a, b = Foo.new # a = 1; b = 2
Om objektet som sönderdelas svarar respond_to?
to_ary
, det behandlas som en grupp med en element:
1.respond_to?(:to_ary) # => false
a, b = 1 # a = 1; b = nil
Nedbrytning kan också kapslas genom att använda ett ()
-begränsat sönderdelningsuttryck istället för vad som annars skulle vara ett enda element:
arr = [1, [2, 3, 4], 5, 6]
a, (b, *c), *d = arr # a = 1; b = 2; c = [3, 4]; d = [5, 6]
# ^^^^^
Detta är faktiskt motsatsen till splatt .
Egentligen kan alla nedbrytningsuttryck avgränsas av ()
. Men för den första nivån sönderdelning är valfritt.
a, b = [1, 2]
(a, b) = [1, 2] # the same thing
Kantfodral: en enda identifierare kan inte användas som ett förstörande mönster, vare sig det är yttre eller en kapslad:
(a) = [1] # SyntaxError
a, (b) = [1, [2]] # SyntaxError
När man tilldelar en matris bokstavligen till ett förstörande uttryck kan yttre []
utelämnas:
a, b = [1, 2]
a, b = 1, 2 # exactly the same
Detta kallas parallelltilldelning , men det använder samma nedbrytning under huven. Detta är särskilt praktiskt för att utbyta värden på variabler utan att använda ytterligare tillfälliga variabler:
t = a; a = b; b = t # an obvious way
a, b = b, a # an idiomatic way
(a, b) = [b, a] # ...and how it works
Värden fångas när du bygger till höger om uppdraget, så att använda samma variabler som källa och destination är relativt säkert.
Vänd flerdimensionell matris till en endimensionell (platt) array
[1, 2, [[3, 4], [5]], 6].flatten # => [1, 2, 3, 4, 5, 6]
Om du har en multidimensionell matris och du måste göra den till en enkel (dvs en-dimensionell) matris kan du använda #flatten
metoden.
Få unika arrayelement
Om du behöver läsa en matriselement och undvika upprepningar använder du #uniq
metoden:
a = [1, 1, 2, 3, 4, 4, 5]
a.uniq
#=> [1, 2, 3, 4, 5]
Om du istället vill ta bort alla duplicerade element från en matris kan du använda #uniq!
metod:
a = [1, 1, 2, 3, 4, 4, 5]
a.uniq!
#=> [1, 2, 3, 4, 5]
Medan utgången är densamma, #uniq!
lagrar också den nya matrisen:
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]
Hämta alla kombinationer / permutationer i en matris
permutation
när det kallas med ett block en tvådimensionell matris bestående av alla ordnade sekvenser i en samling av nummer.
Om den här metoden kallas utan ett block kommer den att returnera en enumerator
. För att konvertera till en matris, anropa to_a
metoden.
Exempel | Resultat |
---|---|
[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 | [] -> Inga permutationer av längd 4 |
combination
å andra sidan, när den kallas med ett block ger en tvådimensionell matris bestående av alla sekvenser i en samling av nummer. Till skillnad från permutation bortses från ordning i kombinationer. Till exempel är [1,2,3]
densamma som [3,2,1]
Exempel | Resultat |
---|---|
[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 | [] -> Inga kombinationer av längd 4 |
Att ringa kombinationsmetoden i sig kommer att resultera i en uppräknare. För att få en matris, ring to_a
metoden.
De repeated_combination
och repeated_permutation
metoder är liknande, förutom samma element kan upprepas flera gånger.
Exempelvis skulle sekvenserna [1,1]
, [1,3,3,1]
, [3,3,3]
inte vara giltiga i vanliga kombinationer och permutationer.
Exempel | # Combo |
---|---|
[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 |
Skapa en matris med pågående nummer eller bokstäver
Detta kan lätt åstadkommas genom att kalla Enumerable#to_a
på ett Range
objekt:
(1..10).to_a #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
(a..b)
betyder att det kommer att inkludera alla siffror mellan a och b. För att utesluta det sista numret använder du a...b
a_range = 1...5
a_range.to_a #=> [1, 2, 3, 4]
eller
('a'..'f').to_a #=> ["a", "b", "c", "d", "e", "f"]
('a'...'f').to_a #=> ["a", "b", "c", "d", "e"]
En bekväm genväg för att skapa en matris är [*a..b]
[*1..10] #=> [1,2,3,4,5,6,7,8,9,10]
[*'a'..'f'] #=> ["a", "b", "c", "d", "e", "f"]
Ta bort alla nollelement från en matris med #compact
Om en matris råkar ha ett eller flera nil
och dessa måste tas bort, Array#compact
eller Array#compact!
metoder kan användas, enligt nedan.
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]
Slutligen märker du att om #compact
eller #compact!
kallas på en matris utan nil
, dessa kommer att returnera noll.
array = [ 'foo', 4, 'life']
array.compact # => nil
array.compact! # => nil
Skapa matris med siffror
Det vanliga sättet att skapa en rad siffror:
numbers = [1, 2, 3, 4, 5]
Räckviddsobjekt kan användas i stor utsträckning för att skapa en rad siffror:
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
och #map
metoder tillåter oss att ställa villkor för antalet intervall:
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]
Alla metoderna ovan laddar siffrorna ivrigt. Om du måste ladda dem lata:
number_generator = (1..100).lazy # => #<Enumerator::Lazy: 1..100>
number_generator.first(10) # => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Cast till Array från alla objekt
Använd Kernel#Array
att få Array från alla objekt.
Följande är ett exempel:
Array('something') #=> ["something"]
Array([2, 1, 5]) #=> [2, 1, 5]
Array(1) #=> [1]
Array(2..4) #=> [2, 3, 4]
Array([]) #=> []
Array(nil) #=> []
Till exempel kan du ersätta join_as_string
metoden från följande kod
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) #=> ""
till följande kod.
def join_as_string(arg)
Array(arg).join(',')
end