Глава п’ята
Масиви…
До цього часу, ми, в цілому, використовували об'єкти поодинці. В цій главі ми дізнаємось, як створити список об'єктів. Розпочнемо із розгляду найбільш поширеного типу структури списку - масиву.
Використання масивів
Що таке масив?
Масив є еквівалентом колекції елементів, в якій кожний елемент може бути пронумерованим.
В Ruby, (на відміну від інших мов) один масив може містити елементи з різними типами даних таких як рядки, цілі числа і числа з плаваючою точкою чи, навіть, виклик методу, який повертає деяке значення:
a1 = [1, 'two', 3.0, array_length(a0)]
Перший елемент масиву має індекс
0
— це означає, що кінцевий елемент має індекс, який дорівнює загальній кількості елементів в масиві мінус1
. За зразком масиваa1
, що показаний вище, ось як отримати значення першого і останнього елементу:
a1[0] # поверне 1ий елемент (з індексом 0) a1[3] # поверне 4ий елемент (з індексом 3)
Ми вже використовували масиви кілька разів, наприклад, в adventure2.rb
в главі 4 ми використовували масив для зберігання карти номерів:
mymap = Map.new([room1,room2,room3])
Створення масивів
Як і багато інших мов програмування, Ruby використовує квадратні дужки для визначення масиву. Ви можете легко створити масив, заповнити його деякими значеннями розділених комами та привласнити його змінній:
arr = ['one','two','three','four']
Як і більшість інших речей в Ruby, масиви є об'єктами. Вони визначені, як неважко здогадатися, класом Array, і, так само, як рядки, вони індексуються від 0.
Ви можете посилатися на елемент в масиві шляхом розміщення його індексу в квадратних дужках. Якщо індекс недійсний, повертається nil
:
array2.rb
:
arr = ['a', 'b', 'c']
puts(arr[0]) # поверне 'a'
puts(arr[1]) # поверне 'b'
puts(arr[2]) # поверне 'c'
puts(arr[3]) # nil
Ви можете змішувати типи даних і, навіть, включати вирази, які дають певне значення. Припустимо, що ви вже створили цей метод:
def hello
return "hello world"
end
Тепер ви можете оголосити цей масив:
x = [1+2, hello, `dir`]
Тут, перший елемент — це ціле число 3
, а другий — рядок "hello world"
(повернутий з методу hello
). Якщо ви запустили код у Windows, третій елемент масиву буде рядком, який містить список директорій. Це пов'язано з тим, що `dir`
це рядок в обернених лапках, який виконується в операційній системі. Фінальний “слот” в масиві, заповнений значеннями, які повернула команда dir
, є рядком з іменами файлів. Якщо Ви запустите це на іншій операційній системі, можливо в такому випадку, вам потрібно буде замінити цю команду.
Створення масиву із імен файлів:
Ряд класів в Ruby мають методи, які повертають масиви значень. Для прикладу, клас
Dir
, який використовується для операцій над дисковими каталогами, має методentries
. Передаючи ім'я директорії в метод і повертаючи список файлів в масиві:
Dir.entries('C:\\') # поверне масив файлів розміщених в каталозі C:\
Якщо ви хочете створити масив рядків, але не хочете турбуватись про друкуванням всіх лапок, це скорочення візьме текст без лапок, який буде розділений лише відступами в круглих дужках поруч з %w ось так:
y = %w(this is an array of strings)
Звичайно, ви можете створити масив, використовуючи звичайний метод побудови об'єкта: new
. При бажанні, ви можете передати ціле число до new
, щоб створити порожній масив специфічного розміру (в якому кожен елемент буде мати значення nil) або ви можете передати два аргументи: перший, щоб встановити розмір масиву і другий, щоб визначити елемент, який буде розміщено в кожному елементі, наприклад:
a = Array.new # порожній масив
a = Array.new(2) # [nil,nil]
a = Array.new(2, "привіт світ") # ["hello world","hello world"]
Багатовимірні масиви
Щоб створити багатомірний масив, ви можете створити один масив, а потім додати інші масиви до кожного зі своїх “слотів”. Наприклад, цей приклад створить масив, що містить два елементи, кожен з яких сам є масивом з двох елементів:
a = Array.new(2)
a[0]= Array.new(2, 'привіт')
a[1]= Array.new(2, 'світ')
Або ви могли б вкласти масиви всередині один одного, використовуючи квадратні дужки. Цей приклад створить масив з чотирьох масивів, кожен з яких містить чотири цілих числа:
a = [ [1,2,3,4],
[5,6,7,8],
[9,10,11,12],
[13,14,15,16] ]
В коді показаному вище, я розмістив чотири “підмасиви” в різних рядках. Це не обов'язково, але це допомагає прояснити структуру багатовимірного масиву шляхом відображення кожного підмасиву так, якби це був рядок, подібно рядкам в таблиці. Коли мова йде про масиви в межах масивів, зручно посилатися на кожен вкладений масив, як “ряд” з “зовнішнього” масиву.
Можливо також створити об'єкт
Array
, передавши масив як аргумент методуnew
. Будьте обережні. Це примха Ruby, хоч й дозволено передавати в масив аргумент без закриття круглих дужок, Ruby буде вважати помилкою, якщо ви пропустите відступ між методомnew
і відкриттям квадратних дужок – це ще одна причина для створення міцної звички використовувати дужки при передачі аргументів!
Для деяких прикладів використання багатовимірних масивів, завантажте програму multi_array.rb
. Вона починається зі створення масиву, multiarr
, який містить два інших масиви. Перший із цих масивів має індекс 0
відносно multiarr
, а інший — 1
:
multiarr = [['one','two','three','four'],[1,2,3,4]]
Перебір масивів
Ви можете отримати доступ до елементів масиву перебираючи їх та використовуючи цикл for
. Цикл обійде два елементи: а саме, два підмасиви з індексами 0 і 1:
for i in multiarr
puts(i.inspect)
end
Це відобразить:
["one", "two", "three", "four"]
[1, 2, 3, 4]
Ітератори і цикли for. Код всередині циклу
for
виконується для кожного елементу. Загальний синтаксис виглядає таким чином:
for <одна або більше змінних> in <вираз> do <код для запуску> end
Коли в наявності більше однієї змінної, вони передаються в код в середині блоку
for..end
так само, як би ви б передавали аргументи в метод. Ось, наприклад, ви можете думати про(a,b,c,d)
як про чотири аргументи, які вже об'явлені, при кожному проході циклуfor
, чотирма значеннями з рядкаmultiarr
:
for (a,b,c,d) in multiarr print("a=#{a}, b=#{b}, c=#{c}, d=#{d}\n") end
Індексація всередині масивів
Ви можете рахувати з кінця масиву, використовуючи знак мінусу, де -1
— це індекс останнього елементу; і ви, також, маєте можливість використовувати діапазони (значення між початковим індексом і кінцевим, розділеними двома крапками):
arr = ['h','e','l','l','o',' ','w','o','r','l','d']
print( arr[0,5] ) #=> „hello‟
print( arr[-5,5 ] ) #=> „world‟
print( arr[0..4] ) #=> „hello‟
print( arr[-5..-1] ) #=> „world‟
Зауважте, що, так як і з рядками, коли надано два цілих числа, щоб повернути багато суміжних пунктів з безлічі, перше число — це початковий індекс, тоді, як друге — це кількість елементів (не індекс):
arr[0,5] # поверне 5 знаків - ["h", "e", "l", "l", "o"]
Ви, також, маєте можливість зробити призначення значень конкретному індексу в масиві. Ось, наприклад, я спочатку створив порожній масив і заповнив елементи з індексами 0, 1 та 3. "Порожній" індекс під номером 2 буде заповнений значенням nil
:
arr = []
arr[0] = [0]
arr[1] = ["one"]
arr[3] = ["a", "b", "c"]
# масив тепер містить:
# [[0], ["one"], nil, ["a", "b", "c"]]
Повторимо ще раз, ви можете використовувати як індекси початку, кінця, діапазони і негативні значення індексів:
arr2 = ['h','e','l','l','o',' ','w','o','r','l','d']
arr2[0] = 'H'
arr2[2,2] = 'L', 'L'
arr2[4..6] = 'O','-','W'
arr2[-4,4] = 'a','l','d','o'
# arr2 тепер містить:
# ["H", "e", "L", "L", "O", "-", "W", "a", "l", "d", "o"]