Szukaj…


Składnia

  • a = [] # używając literału tablicowego
  • a = Array.new # równoważne użyciu literału
  • a = Array.new (5) # utwórz tablicę z 5 elementami o wartości zero.
  • a = Array.new (5, 0) # utwórz tablicę z 5 elementami o domyślnej wartości 0.

#mapa

#map , dostarczone przez Enumerable, tworzy tablicę, wywołując blok na każdym elemencie i zbierając wyniki:

[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]

Oryginalna tablica nie jest modyfikowana; zwracana jest nowa tablica zawierająca przekształcone wartości w tej samej kolejności co wartości źródłowe. map! można użyć, jeśli chcesz zmodyfikować oryginalną tablicę.

W metodzie map można wywołać metodę lub użyć proc do wszystkich elementów w tablicy.

# 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 jest synonimem collect .

Tworzenie tablicy za pomocą dosłownego konstruktora []

Tablice można tworzyć, umieszczając listę elementów w nawiasach kwadratowych ( [ i ] ). Elementy tablicy w tej notacji są oddzielone przecinkami:

array = [1, 2, 3, 4]

Tablice mogą zawierać dowolne obiekty w dowolnej kombinacji bez ograniczeń typu:

array = [1, 'b', nil, [3, 4]]

Utwórz tablicę ciągów

Tablice ciągów znaków można tworzyć przy użyciu składni procentowej ciągu ruby:

array = %w(one two three four)

Jest to funkcjonalnie równoważne zdefiniowaniu tablicy jako:

array = ['one', 'two', 'three', 'four']

Zamiast %w() możesz użyć innych pasujących par ograniczników: %w{...} , %w[...] lub %w<...> .

Możliwe jest również użycie dowolnych niealfanumerycznych ograniczników, takich jak: %w!...! , %w#...# lub %w@...@ .

Można użyć %W zamiast %w do włączenia interpolacji łańcucha. Rozważ następujące:

var = 'hello'

%w(#{var}) # => ["\#{var}"]
%W(#{var}) # => ["hello"]

Wiele słów można interpretować, uciekając spacją za pomocą \.

%w(Colorado California New\ York) # => ["Colorado", "California", "New York"]

Utwórz tablicę symboli

2.0
array = %i(one two three four)

Tworzy tablicę [:one, :two, :three, :four] .

Zamiast %i(...) możesz użyć %i{...} lub %i[...] lub %i!...!

Dodatkowo, jeśli chcesz użyć interpolacji, możesz to zrobić za pomocą %I

2.0
a = 'hello'
b = 'goodbye'
array_one = %I(#{a} #{b} world)
array_two = %i(#{a} #{b} world)

Tworzy tablice: array_one = [:hello, :goodbye, :world] array_two = [:"\#{a}", :"\#{b}", :world] array_one = [:hello, :goodbye, :world] and array_two = [:"\#{a}", :"\#{b}", :world]

Utwórz tablicę za pomocą Array :: new

Pusty Array ( [] ) można utworzyć za pomocą metody klasy Array::new , Array::new :

Array.new    

Aby ustawić długość tablicy, przekaż argument liczbowy:

Array.new 3 #=> [nil, nil, nil]

Istnieją dwa sposoby zapełnienia tablicy wartościami domyślnymi:

  • Przekaż niezmienną wartość jako drugi argument.
  • Przekaż blok, który pobiera bieżący indeks i generuje zmienne wartości.
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"]

Manipulowanie elementami macierzy

Dodawanie elementów:

[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]]

Usuwanie elementów:

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

Łączenie tablic:

[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]

Możesz także pomnożyć tablice, np

[1, 2, 3] * 2
# => [1, 2, 3, 1, 2, 3]

Tablica unii, przecięcia i różnicy

x = [5, 5, 1, 3]
y = [5, 2, 4, 3]

Unia ( | ) zawiera elementy z obu tablic, z usuniętymi duplikatami:

x | y
=> [5, 1, 3, 2, 4]

Przecięcie ( & ) zawiera elementy, które są obecne zarówno w pierwszej, jak i drugiej tablicy:

x & y
=> [5, 3]

Różnica ( - ) zawiera elementy, które są obecne w pierwszej tablicy i nie występują w drugiej tablicy:

x - y
=> [1]

Filtrowanie tablic

Często chcemy operować tylko na elementach tablicy, które spełniają określony warunek:

Wybierz

Zwróci elementy pasujące do określonego warunku

array = [1, 2, 3, 4, 5, 6]
array.select { |number| number > 3 } # => [4, 5, 6]

Odrzucać

Zwróci elementy, które nie pasują do określonego warunku

array = [1, 2, 3, 4, 5, 6]
array.reject { |number| number > 3 } # => [1, 2, 3]

Zarówno #select jak i #reject zwracają tablicę, dzięki czemu można je łączyć:

array = [1, 2, 3, 4, 5, 6]
array.select { |number| number > 3 }.reject { |number| number < 5 }
  # => [5, 6]

Wstrzyknąć, zmniejszyć

Wstrzykiwanie i zmniejszanie to różne nazwy dla tej samej rzeczy. W innych językach funkcje te są często nazywane fałdami (np. Foldl lub foldr). Te metody są dostępne dla każdego obiektu Enumerable.

Wtrysk przyjmuje funkcję dwóch argumentów i stosuje ją do wszystkich par elementów w tablicy.

Do tablicy [1, 2, 3] możemy dodać je wszystkie wraz z wartością początkową zero, określając wartość początkową i blok w następujący sposób:

[1,2,3].reduce(0) {|a,b| a + b} # => 6

Tutaj przekazujemy funkcji wartość początkową i blok, który mówi, aby dodać wszystkie wartości razem. Blok jest najpierw uruchamiany z 0 jako a i 1 jako b , a następnie przyjmuje wynik tego jako następny a więc dodajemy 1 do drugiej wartości 2 . Następnie bierzemy wynik tego ( 3 ) i dodajemy go do ostatniego elementu na liście (również 3 ), podając nasz wynik ( 6 ).

Jeśli pominiemy pierwszy argument, ustawi a jako pierwszy element na liście, więc powyższy przykład jest taki sam jak:

[1,2,3].reduce {|a,b| a + b} # => 6

Ponadto zamiast przekazywać blok z funkcją, możemy przekazać nazwaną funkcję jako symbol, albo z wartością początkową, albo bez. Dzięki temu powyższy przykład można zapisać jako:

[1,2,3].reduce(0, :+) # => 6

lub pomijając wartość początkową:

[1,2,3].reduce(:+) # => 6

Dostęp do elementów

Możesz uzyskać dostęp do elementów tablicy według ich indeksów. Numeracja indeksu tablicy zaczyna się od 0 .

%w(a b c)[0] # => 'a'
%w(a b c)[1] # => 'b'

Możesz przyciąć tablicę za pomocą zasięgu

%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)

Zwraca nową tablicę, ale nie wpływa na oryginał. Ruby obsługuje również stosowanie ujemnych wskaźników.

%w(a b c)[-1] # => 'c'
%w(a b c)[-2] # => 'b'

Możesz także łączyć wskaźniki ujemne i dodatnie

%w(a b c d e)[1...-1] # => ['b', 'c', 'd']

Inne przydatne metody

Użyj first aby uzyskać dostęp do pierwszego elementu w tablicy:

[1, 2, 3, 4].first # => 1

Lub first(n) aby uzyskać dostęp do pierwszych n elementów zwróconych w tablicy:

[1, 2, 3, 4].first(2) # => [1, 2]

Podobnie dla last i last(n) :

[1, 2, 3, 4].last    # => 4
[1, 2, 3, 4].last(2) # => [3, 4]

Użyj sample aby uzyskać dostęp do losowego elementu w tablicy:

[1, 2, 3, 4].sample  # => 3
[1, 2, 3, 4].sample  # => 1

Lub sample(n) :

[1, 2, 3, 4].sample(2) # => [2, 1]
[1, 2, 3, 4].sample(2) # => [3, 4]

Tablica dwuwymiarowa

Korzystając z konstruktora Array::new , możesz zainicjować tablicę o danym rozmiarze i nową tablicę w każdym z jej gniazd. Wewnętrzne tablice mogą mieć również rozmiar i wartość początkową.

Na przykład, aby utworzyć tablicę zer 3x4:

array = Array.new(3) { Array.new(4) { 0 } }

Tablica wygenerowana powyżej wygląda tak po wydrukowaniu za pomocą p :

[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]

Możesz czytać lub pisać do takich elementów:

x = array[0][1]
array[2][3] = 2

Tablice i operator splat (*)

Za pomocą operatora * można rozpakować zmienne i tablice, aby można je było przekazywać jako indywidualne argumenty do metody.

Można tego użyć do zawinięcia pojedynczego obiektu w tablicy, jeśli nie jest on jeszcze:

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)
#> []

W powyższym przykładzie metoda wrap_in_array przyjmuje jeden argument, value .

Jeśli value jest Array , jej elementy są rozpakowywane i tworzona jest nowa tablica zawierająca ten element.

Jeśli value jest pojedynczym obiektem, tworzona jest nowa tablica zawierająca ten pojedynczy obiekt.

Jeśli value wynosi nil , value jest pusta tablica.

Operator splat jest szczególnie przydatny, gdy w niektórych przypadkach jest wykorzystywany jako argument w metodach. Na przykład, umożliwia nil , pojedyncze wartości i macierze mają być obsługiwane w zgodny sposób:

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

Rozkład

Dowolną tablicę można szybko rozłożyć , przypisując jej elementy do wielu zmiennych. Prosty przykład:

arr = [1, 2, 3]
# ---
a = arr[0]
b = arr[1]
c = arr[2]
# --- or, the same
a, b, c = arr

Poprzedzenie zmiennej operatorem splat ( * ) wstawia do niej tablicę wszystkich elementów, które nie zostały przechwycone przez inne zmienne. Jeśli nie ma żadnych, przypisywana jest pusta tablica. W jednym zadaniu można użyć tylko jednej ikony:

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 *

Rozkład jest bezpieczny i nigdy nie powoduje błędów. nil jest przypisywane tam, gdzie nie ma wystarczającej liczby elementów, pasujących do zachowania operatora [] podczas uzyskiwania dostępu do indeksu poza granicami:

arr[9000] # => nil
a, b, c, d = arr # a = 1; b = 2; c = 3; d = nil

Dekompozycja próbuje niejawnie wywołać to_ary na przypisywanym obiekcie. Wdrażając tę metodę w swoim typie, zyskujesz możliwość jej rozkładu:

class Foo
  def to_ary
    [1, 2]
  end
end
a, b = Foo.new # a = 1; b = 2

Jeśli rozkładany obiekt nie respond_to? to_ary , jest traktowany jako tablica jednoelementowa:

1.respond_to?(:to_ary) # => false
a, b = 1 # a = 1; b = nil

Dekompozycję można również zagnieżdżać , używając wyrażenia dekompozycji ograniczonego () zamiast tego, co w innym przypadku byłoby pojedynczym elementem:

arr = [1, [2, 3, 4], 5, 6]
a, (b, *c), *d = arr # a = 1; b = 2; c = [3, 4]; d = [5, 6]
#   ^^^^^

Jest to faktycznie przeciwieństwo splat .

Właściwie każde wyrażenie dekompozycji może być rozdzielane przez () . Ale dla pierwszego poziomu rozkład jest opcjonalny.

a, b = [1, 2]
(a, b) = [1, 2] # the same thing

Przypadek krawędzi: pojedynczego identyfikatora nie można użyć jako wzorca destrukcji, zewnętrznego lub zagnieżdżonego:

(a) = [1] # SyntaxError
a, (b) = [1, [2]] # SyntaxError

Przypisując literał tablicowy do wyrażenia destrukcyjnego, external [] można pominąć:

a, b = [1, 2]
a, b =  1, 2  # exactly the same

Jest to znane jako przypisanie równoległe , ale wykorzystuje ten sam rozkład pod maską. Jest to szczególnie przydatne do wymiany wartości zmiennych bez stosowania dodatkowych zmiennych tymczasowych:

t = a; a = b; b = t # an obvious way
a, b = b, a         # an idiomatic way
(a, b) = [b, a]     # ...and how it works

Wartości są przechwytywane podczas budowania prawej strony zadania, więc użycie tych samych zmiennych co źródło i miejsce docelowe jest względnie bezpieczne.

Zamień tablicę wielowymiarową w tablicę jednowymiarową (spłaszczoną)

[1, 2, [[3, 4], [5]], 6].flatten  # => [1, 2, 3, 4, 5, 6]

Jeśli masz tablicę wielowymiarową i musisz uczynić ją prostą (tj. Jednowymiarową) tablicą, możesz użyć metody #flatten .

Uzyskaj unikalne elementy tablicy

Jeśli chcesz odczytać elementy tablicy unikając powtórzeń , użyj metody #uniq :

a = [1, 1, 2, 3, 4, 4, 5]
a.uniq
#=> [1, 2, 3, 4, 5]

Zamiast tego, jeśli chcesz usunąć wszystkie zduplikowane elementy z tablicy, możesz użyć #uniq! metoda:

a = [1, 1, 2, 3, 4, 4, 5]
a.uniq!
#=> [1, 2, 3, 4, 5]

Chociaż wynik jest taki sam, #uniq! przechowuje również nową tablicę:

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]

Uzyskaj wszystkie kombinacje / permutacje tablicy

Metoda permutation , wywołana z blokiem, daje dwuwymiarową tablicę składającą się ze wszystkich uporządkowanych sekwencji zbioru liczb.

Jeśli ta metoda zostanie wywołana bez bloku, zwróci enumerator . Aby przekonwertować na tablicę, wywołaj metodę to_a .

Przykład Wynik
[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 [] -> Brak permutacji o długości 4

Z drugiej strony metoda combination wywołana blokiem daje dwuwymiarową tablicę składającą się ze wszystkich sekwencji zbioru liczb. W przeciwieństwie do permutacji, porządek jest pomijany w kombinacjach. Na przykład [1,2,3] jest taki sam jak [3,2,1]

Przykład Wynik
[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 [] -> Brak kombinacji długości 4

Samo wywołanie metody kombinacji spowoduje wyliczenie. Aby uzyskać tablicę, wywołaj metodę to_a .

Metody repeated_combination i repeated_permutation są podobne, z tym wyjątkiem, że ten sam element można powtórzyć wiele razy.

Na przykład sekwencje [1,1] , [1,3,3,1] , [3,3,3] nie byłyby prawidłowe w regularnych kombinacjach i permutacjach.

Przykład # Kombinacje
[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

Utwórz tablicę kolejnych cyfr lub liter

Można to łatwo osiągnąć, wywołując Enumerable#to_a na obiekcie Range :

(1..10).to_a    #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

(a..b) oznacza, że będzie zawierać wszystkie liczby od a do b. Aby wykluczyć ostatni numer, użyj a...b

a_range = 1...5
a_range.to_a       #=> [1, 2, 3, 4]

lub

('a'..'f').to_a    #=> ["a", "b", "c", "d", "e", "f"]
('a'...'f').to_a   #=> ["a", "b", "c", "d", "e"]

Wygodnym skrótem do tworzenia tablicy jest [*a..b]

[*1..10]           #=> [1,2,3,4,5,6,7,8,9,10]
[*'a'..'f']        #=> ["a", "b", "c", "d", "e", "f"]

Usuń wszystkie elementy zerowe z tablicy za pomocą #compact

Jeśli tablica zawiera jeden lub więcej elementów nil i należy je usunąć, Array#compact lub Array#compact! metody mogą być stosowane, jak poniżej.

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]

Na koniec zauważ, że jeśli #compact lub #compact! są wywoływane w tablicy bez elementów nil , zwracają zero.

array = [ 'foo', 4, 'life']

array.compact # => nil

array.compact! # => nil

Utwórz tablicę liczb

Normalny sposób tworzenia tablicy liczb:

numbers = [1, 2, 3, 4, 5]

Obiekty zakresu mogą być szeroko stosowane do tworzenia tablicy liczb:

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 i #map pozwalają nam nałożyć warunki na zakres liczb:

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]

Wszystkie powyższe metody chętnie ładują liczby. Jeśli musisz je ładować leniwie:

number_generator = (1..100).lazy # => #<Enumerator::Lazy: 1..100>

number_generator.first(10) # => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Rzucaj na Array z dowolnego obiektu

Aby uzyskać tablicę z dowolnego obiektu, użyj Kernel#Array .

Oto przykład:

Array('something') #=> ["something"]
Array([2, 1, 5])   #=> [2, 1, 5]
Array(1)           #=> [1]
Array(2..4)        #=> [2, 3, 4]
Array([])          #=> []
Array(nil)         #=> []

Na przykład możesz zastąpić metodę join_as_string z następującego kodu

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)         #=> ""

do następującego kodu.

def join_as_string(arg)
  Array(arg).join(',')
end


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow