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

2,0
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

2,0
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


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow