4-1 Dãy thứ tự

4-1 Dãy thứ tự

Hầu hết những ngôn ngữ lập trình đều có chức năng tên là Dãy thứ tự. Tất nhiên, trong Ruby cũng có thể sử dụng chức năng này.

100 con slime

Trong trường hợp cần gọi 100 con slime thì chúng ta phải làm thế nào? Tất nhiên cũng có phương pháp như sau

monster0 = "Slime"
monster1 = "Slime"
.
.
.
monster99 = "Slime"

Chúng ta tạo 100 biến số monster0~monster99, và để cho nó thay thế cho dãy chữ "Slime". Nhưng phải viết lại 100 lần cụm như vậy thì quá vất vả. Tại đây chúng ta có một thứ tiện lợi tên là dãy thứ tự. Tôi sẽ giải thích ngắn gọn về chuỗi thứ tự (Array) này.

monsters = []  # Tại một dãy thứ tự mà monsters
100.times do
  monster << "Slime"  # thêm vào dãy slime
end

Như vậy chúng ta đã lập một chuỗi Object tên là monsters và sẽ đưa lần lượt chữ slime vào chuỗi 100 con như vậy.

monsters << "Slime"

có nghĩa là với mỗi dãy chứ "Slime" như vậy thì ta sẽ cho vào dãy Monsters. Lệnh này được chạy 100 lần nên chúng ta có được 100 con "Slime" trong dãy [monsters] Có nghĩa là chúng ta có thể đưa vào dãy thứ tự từng dãy chữ phức tạp khác nhau.

Tạo dãy thứ tự

Từ đây tôi sẽ dần dần giới thiệu về dãy thứ tự. Đầu tiên phần này sẽ giới thiệu về cách tạo dãy thứ tự. Để tạo một dãy thứ tự thì chúng ta tạo chương trình như sau.

a = [] # dãy trống

Từ đây ta tạo object cho dãy thứ tự là biến số a. Chúng ta cũng có thể có cách viết như sau.

a = [1,2,3]

Hoặc chúng ta cũng có thể có cách viết

a = ["A","B","C"]

Như trên, chúng ta có thể tạo dãy bằng []

tên biến số = [Object0, object1,...]

Tại dãy thì chúng ta có thể điền vào những Object khác nhau. Trong những Object về giá trị số hay dãy chữ thì chúng ta phân biệt giữa những object bằng dấu [,] và nội dung phải được bao trong dấu [] Những object được tạo ra sẽ được đặt tên sử dụng các biến số. Chúng ta hãy dùng lệnh [p] để gọi hiển thị dãy thứ tự.

a = []
p a # => []
a = [1,2,3]
p a
a= ["A","B","C"]
p a

Dùng lệnh p như vậy chúng ta sẽ xác định được nội dung bên trong dãy.

Tại Ruby thì việc lập nên một dãy thì thật dễ dàng đúng không? Nếu chúng ta sử dụng dãy, coi như một biến số, có thể quản lý nhiều object khác nhau.

Truy cập thành tố bên trong dãy

Những object được điền bên trong dãy sẽ được ghi nhớ theo thứ tự. Để truy cập vào những Object được ghi trong dãy rất đơn giản. Ví dụ, nếu muốn hiển thị thành tố đầu tiên trong dãy thì chúng ta làm như sau.

a = ["A", "B", "C"]
p a[0]

Chúng ta viết [0] ngay đằng sau biến số a, như vậy sẽ truy cập được vào thành tố đầu tiên trong dãy. Để truy cập vào thành tố thứ 2, thứ 3 trong dãy thì chúng ta làm như chương trình dưới đây.

a = ["A", "B", "C"]
p a[1]
p a[2]

Đây là điều cần chú ý. Khi truy cập vào dãy thì chúng ta sẽ truy cập theo thứ tự từ đầu là [0,1,2]. Vậy khi truy cập vào thành tố chưa được ghi nhớ thì kết quả sẽ trả về thế nào?

a = ["A", "B", "C"]
p a[3] # => nil
p a[100] # => nil

Nếu chúng ta đăng nhập vào thành tố không tồn tại thì kết quả trả về sẽ là [nil].

Biểu thị sự không có gì [nil]

[nil] là Object (giá trị) biểu thị sự không có gì. Nếu chúng ta truy cập vào giá trị không có trong dãy thì kết quả sẽ trả lại là [nil].

a = []
p a[0] # => nil

Chúng ta cũng có thể biểu thị [nil] bằng biến số.

a = nill
p a		# => nill

[nil] khi dùng trong câu [if] hay câu [while] thì sẽ được hiểu câu điều kiện đó sai.

if nill
  puts "Hello"	# lệnh không được thực hiện
end

while nill
  puts "Hello"	# lệnh không được thực hiện
end

Thay đổi thành tố trong dãy

Chúng ta hãy thử thay đổi các thành tố trong dãy.

a = []
a[0] = "Hello"

Để thay thế, chúng ta dùng [=]. Như vậy thành tố đầu tiên trong dãy được thay là "Hello". Tiếp theo chúng ta cũng có thể thay đổi các thành tố thứ 2, thứ 3 trong dãy như sau.

a[1] = 100
a[2] = bye

Chúng ta dùng lệnh p để xác nhận nội dung.

p a # => ["Hello", 100, "Bye"]

Chúng ta cũng có thể gọi lần lượt từng thành tố ra.

 p a[0]	# => "Hello"
 p a[1]    # => 100

Khi chúng ta thay đổi giá trị trong dãy, không nhất thiết chúng ta phải thay đổi thêm vào theo thứ tự từ đầu.

 a = []
 a[3] = "Hello"
 p a	# => [nil, nil, nil, "Hello"]

Như trên, đối với một dãy mà chúng ta chỉ điền giá trị thứ 4 thì những giá trị còn lại đứng trước nó sẽ được biểu thị bằng [nil]

Thêm thành tố vào cuối của dãy thứ tự

Có phương pháp để cho thêm thành tố vào cuối dãy thứ tự

 a = ["Hello", "Hi"]
 a.push "Bye"
 p a	# => ["Hello", "Hi", 100]

Khi ta muốn thêm thánh tố vào cuối dãy thì sử dụng lệnh [push]. Lệnh [push] sẽ thêm thành tố vào vị trí cuối cùng của câu.

Nếu sử dụng [<<] thì cũng giống như chúng ta sử dụng lệnh [push] và thêm được thành tố vào cuối dãy.

 a = ["Hello", "Hi"]
 a << "Bye"
 p a	# => ["Hello", "Hi", "Bye"]

Lệnh [<<] và [push] là hai lệnh hoàn toàn giống nhau.

Quay lại 100 con slime

Chúng ta hãy nhìn lại chương trình được giới thiệu từ đầu.

 monsters = []
 100.times do
   monsters << "Slime"
 end

Chúng ta hãy hiểu vấn đề lại một lần nữa nhé. Lập ra dãy trống [monsters] và cho vào 100 con slime. Chúng ta hãy thử xây dựng lại chương trình một lần nữa

 monsters = []
 i = 0
   while i<100
   monsters << "Slime #{i}"
   i += 1
 end

Như vậy chúng ta sẽ có thêm số đằng sau chữ Slime và dãy sẽ trở thành như sau.

 "Slime0", "Slime1", "Slime2",...

Chúng ta thử biểu thị theo thứ tự từng thành tố một trong dãy monsters

 i = 0
 while i<100
   puts monsters[i]
   i += 1
 end

[Kết quả hiển thị]

 slime0
 slime1
 slime2
 .
 .
 .
 slime99

Lệnh về kích thước

Tại dãy, chúng ta được chuẩn bị những lệnh rất tiện lợi để thao tác dễ dàng hơn trong dãy. Phần dưới đây sẽ giới thiệu những lệnh đại biểu được chuẩn bị sẵn.

Để có được kích thước của dãy (só phần tử trong dãy) thì chúng ta có lệnh [size]

a = ["Hello","Hi","Bye"]
p a.size	# => 3

Đối với dãy trống thì size trả về sẽ là 0

a = []
p a.size	# =>0

Lệnh push và pop

Nếu chúng ta chạy lệnh [push] trong dãy thì chúng ta sẽ thêm được thành tố vào cuối dãy.

a = []
a.push 0	# thêm 0 vào a
p a	     # => [0]
a.push 1
p a	     # => [0, 1]

Còn lệnh [pop] là ngược với [push] sẽ lấy đi thành tố ở cuối dãy.

a = ["a", "b"]
a.pop
p a	# => ["a"]
a.pop
p a	# => []

Đối với dãy thứ tự, khi ta chạy lệnh [pop] thì sẽ lấy dần đi thành tố ở cuối dãy, nếu lấy hết mà ta vẫn chạy lệnh thì kết quả trả về sẽ là nil.

Lệnh unshift và shift

Trong dãy thứ tự, khi ta dùng lệnh [únhift] thì chúng ta có thể thêm thành tố vào đầu dãy.

a = []
a.unshift 0
p a	# =>[0]
a.unshift 1
p a	# => [1,0]

Cũng tương tự, ngược với nó là lệnh shift để lần lượt xóa đi thành tố ở đầu câu.

a = [0,1]
a.shift
p a	# => [1]
a.shift
p a	# => []

Nếu chúng ta thực hiện lệnh [shift] đối với dãy thì thành tố từ đầu dãy sẽ bị xóa dần. Nếu trong dãy đã trống mà chúng ta còn sử dụng lệnh [shift] thì kết quả sẽ trả lại là [nil].

Lệnh each

Tại dãy, lệnh [each] là lệnh yêu cầu xử lý lặp lại đối với những thành tố trong dãy

a = ["Hello", "Hi", "Bye"]
a.each do |e|
  puts e
end

[Kết quả hiển thị]

Hello
Hi
Bye
Về xử lý xử dụng lệnh [each] để lặp đi lặp lại, chúng ta sẽ tìm hiểu rõ hơn trong [Lệnh kèm block] trong trang 160

Liên kết các dãy bằng [+]

Như dưới đây, chúng ta có thể ghép hai dãy sử dụng dấu [+] để tạo ra một dãy mới.

a = ["Hello", "bye"]
b = [0, 5]
c = a + b
p c	# => ["Hello", "hi", 0, 5]

Tạo dãy trong dãy

Chúng ta có thể tạo Object ngay trong dãy. Nội dung trong dãy cũng chính là Object nên chúng ta cũng có thể tạo được dãy trong dãy.

a = [0,1]
b = [2,3,a]
p b	   # => [2,3,[0,1]]

p b[0]	# => 2
p b[2]	# => [0,1]

Cũng như vậy, chúng ta có thể truy cập vào những thành tố của dãy bên trong dãy.

b = [2, 3, [0, 1]]
p b[2]	   # => [0, 1]
p b[2][0]	# => 0
p b[2][1]	# => 1

Dùng dãy để dự báo thời tiết

Phần này sẽ giới thiệu cách dùng dãy để "Dự báo thời tiết" Chúng ta cho vào dãy những kết quả hiển thị trước, thực hiện lệnh để các thành tố trong dãy hiển thị một cách ngẫu nhiên.

a = ["Ngày mai trời đẹp", "Ngày mai trời mưa", "Ngày mai trời có mây"]
size = a.size
r = rand(size)
puts a[r]

Trong dãy a có 3 thành tố, bằng lệnh [a.size] thì sẽ được số thành tố là 3. Như trên, nếu chúng ta lấy giá trị mà [a.size] lấy được đưa cho lệnh [rand] thì khi chúng ta thay đổi nội dung trong dãy [a] thì cũng không sao cả.

Tuy nhiên chúng ta cũng có thể viết chương trình trên như sau:

a = ["nắng", "mưa", "mây"]
puts "Thời tiết hôm nay #{a[rand(a.size)]}"

Chương trình này giống hoàn toàn chương trình trên. Mọi người hãy thử dần dần chạy từng chương trình xem sao.