+3

Những điều thú vị có thể bạn chưa biết về Array trong Ruby

Chúng ta làm việc với array rất nhiều nhưng chắc hẳn có nhiều điều thú vị dưới đây mà bạn chưa biết đến. Hãy bắt đầu tìm hiểu nhé 😃)

Mở màn phát nào

arr = [1, 2, 3]
arr[9] = 'foo'
p arr # => [1, 2, 3, nil, nil, nil, nil, nil, nil, "foo"]

Khi ta gán 1 giá trị vào vị trí > độ dài của mảng => mảng tự động thêm những giá trị nil vào chỗ trống, độ dài mảng tăng lên.

Khởi tạo mảng mới

arr = Array.new # => []

Hoạt động tương tự khi ta sử dụng arr = []. ngoài ra chúng ta có thể định nghĩa độ dài và giá trị mặc định của Array như sau:

arr = Array.new(3, 'foo') # => ["foo", "foo", "foo"]
arr[6] = 'bar'
p arr # => ["foo", "foo", "foo", nil, nil, nil, "bar"]

Chúng ta có thể sử dụng block để tạo giá trị cho Array:

arr = Array.new(3) { |i| "item-#{i}" }
p arr # => ["item-0", "item-1", "item-2"]

Bạn đã từng gặp trường hợp nào như thế này chưa:

arr = Array.new(2, Hash.new)
p arr # => [{}, {}]
arr[0][:foo] = 'bar'
p arr # => [{:foo=>"bar"}, {:foo=>"bar"}]

khắm lọ quá. Lý do như vậy bởi vì 2 element đều tham chiếu đến cùng 1 đối tượng Hash đó. Để khắc phục nó thì ta xử lý như sau:

arr = Array.new(2) { Hash.new }
p arr # => [{}, {}]
arr[0][:foo] = 'bar'
p arr # => [{:foo=>"bar"}, {}]

Bây giờ thì ngon rồi, mỗi element tham chiếu tới 2 hask khác nhau.

1 cách kkhởi tạo Array tiếp cho anh em tham khảo:

arr = Array(3) # => [3]
arr = Array([1,2,3]) # => [1,2,3]

Slicing

arr = [1,2,3,4]
arr[0]  # => 1
arr[20] # => nil

arr[0] thì quá bình thường, còn arr[20] = nil thì có vẻ mới đúng ko ạ :v Chúng ta cũng có thể cắt theo độ dài chuỗi như sau:

arr = [1,2,3,4]
arr[0, 2]  # => [1, 2]
arr = [1,2,3,4]
p arr[0..2] # => [1, 2, 3]

các trường hợp trên đều trả về 1 array mới, nếu bạn muốn thay đổi trực tiếp lên mảng thì sử dụng method slice!

arr = [1, 2, 3]
arr.slice!(1, 2) # => [2, 3]
p arr # => [1]

Inserting

Ok, bạn muốn thêm phần tử vào mảng thì sao?

arr = [1,2,3]
arr.insert(1, [10, 20])
p arr # => [1, [10, 20], 2, 3]

Thêm 1 mảng [10,20] vào vị trí thứ 2 của mảng. Hoặc nếu chỉ muốn thêm các gía trị của 1 mảng vào 1 mảng thì ta sử dụng như sau:

   arr.insert(1, [10, 20]).flatten! # => [1, 10, 20, 2, 3]

Nhưng chúng ta còn có 1 cách thú vị hơn nhiều 😃 Đó là:

arr = [1,2,3]
arr.insert(1, *[10, 20]) 
p arr # => [1, 10, 20, 2, 3]

Hoặc:

arr = [1,2,3]
arr[0..0] = [10, 20]
p arr # => [10, 20, 2, 3]

Rất đơn giản phải không nào!

Comparing arrays

Để so sánh 2 mảng, chúng ta có thể sử dụng ký tự <=>. Trả về (-1, 0, 1) tương ứng với nhỏ hơn, bằng, lớn hơn. 2 Mảng sẽ so sánh lần lượt từng element tại từng index từ trái qua phải. Ví dụ:

arr = [1,2,3]
another_arr = [1,2,4]

arr <=> another_arr # => -1

arr = [1, 2, 3]
another_arr = [1, 2, 3]

arr <=> another_arr # => 0

Nếu bất kỳ phần tử của array đầu tiên lớn hơn phần tử tương ứng của array kia thì sẽ trả về 1.

arr = [1, 5, 3]
another_arr = [1, 2, 3]

arr <=> another_arr # => 1 (5 lớn hơn 2) What if elements of arrays are not comparable? Let's see: Trường hợp 2 element của 2 array không so sánh được:

arr = [1, 5, 3]
another_arr = [1, "test", 3]
arr <=> another_arr # => nil

Trong trường hợp 2 mảng có size khác nhau:

arr = [1, 2, 3]
another_arr = [1, 2, 3, 4]
p arr <=> another_arr # => -1

arr = [1, 2, 3, 4, 5]
another_arr = [1, 2]

arr <=> another_arr # => 1

Trường hợp cộng 2 mảng có trùng phần tử:

arr = [1, 1, 2, 2]
arr = ["foo", "bar"]
arr2 = ["bar", "baz"]
arr + arr2 # => ["foo", "bar", "bar", "baz"]

"bar" bị duplicate lên. Trong trường hợp chúng ta không muốn duplicate thì sử dụng như sau:

arr = ["foo", "bar"]
arr2 = ["bar", "baz"]

p arr | arr2 # => ["foo", "bar", "baz"]

Bài viết của mình cung cấp 1 số hàm, toán tử và một vài phép toán thú vị mà không hẳn tất cả mọi người đều biết. hi vọng bài viết sẽ giúp ích cho mọi người.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí