- vừa được xem lúc

6 vòng lặp Ruby nâng cao

0 0 94

Người đăng: Chu Ngoc Minh

Theo Viblo Asia

Ruby là ngôn ngữ với nguyên tắc "tối ưu hóa cho nhà phát triển". Đó là một ngôn ngữ dễ đọc, dễ viết, tích hợp, mẫu và nguyên mẫu cùng với các lợi ích khác. Một trong những tính năng tốt nhất của nó là cung cấp các phương thức trợ giúp cho nhiều phương thức thường được sử dụng. Lặp lại, sắp xếp, lọc, chuyển đổi và các phương thức khác đều có nhiều helper trợ giúp được tích hợp sẵn trong ngôn ngữ (có thể liệt kê trong mô-đun).

Bạn có thể tập trung vào logic của mình nhiều hơn và ít hơn vào việc viết các helper trợ giúp lặp lại đã được hỗ trợ sẵn. Điều làm cho code dễ đọc hơn.

Các phương thức trợ giúp này trừu tượng hóa các chi tiết về cách lặp lại xảy ra và cung cấp cho logic của chính nó. Vì code được đọc thường xuyên hơn nhiều so với được viết, nên nó cũng giúp code hiệu quả hơn.

Tôi muốn xem qua một số vòng lặp Ruby ít được biết đến. Những điều này sẽ làm cho code ít dài dòng hơn, dễ đọc hơn và viết nhanh hơn:

1. map
2. each_with_object
3. each_with_index
4. partition
5. select/reject
6. any?/all?

Lưu ý: Tất cả các phương thức này sẽ hoạt động cho cả arrays và hashes. Cả hai đều được coi là liệt kê.

map

Hữu ích cho việc tạo một mảng từ một mảng có sẵn và áp dụng một số logic nhất định cho từng phần tử. Ví dụ: bình phương từng giá trị trong một mảng. Vì vậy, thay vì sử dụng từng thành phần để lặp lại và chèn kết quả vào một mảng khác, bạn chỉ có thể sử dụng map.

# ok: Instead of using each and appending to a var
def build_array(nums)
result = []
nums.each do |num|
result << calculate(num)
end
result
end
# better: You can just use map
def build_array(nums)
result = nums.map { |num| calculate(num) }
end
# best: Or even shorter.
def build_array(nums)
result = nums.map(&:calculate)
end
# Actually, we can skip this method and just inline `result = nums.map(&:calculate)`.

each_with_object

Hữu ích để tạo một đối tượng bằng cách lặp qua một số liệu. Ví dụ: muốn tạo một hashes từ một array? Hay một đối tượng Person từ một hashes đã cho?

# ok: you can use an instantiated hash, which isnt pretty
def build_hash(nums) h = {} nums.each { |num| h[num] = calculate(num) } h
end # better: or you can use each_with_object
def build_hash(nums) # it receives the object to start with ({}) and accumulates on top of it nums.each_with_object({}) { |num, res| res[num] = calculate(num) }
end # bonus: works with any kind of object
def build_array(nums) # you can replace the accumulator to be an array, or any object really. nums.each_with_object([]) { |num, res| res << calculate(num) }
end

each_with_index

Hữu ích khi, ngoài việc lặp qua một số liệu, bạn cũng cần sử dụng chỉ mục. Ví dụ: Cần ghi lại chỉ mục hiện tại mà chúng ta đang xử lý?

# ok: Let's print a stauts log before each iteration
def handle(nums) num_count = nums.count # we can use the count to iterate for i in 0..num_count do Rails.logger.info("Handling item #{i}/#{num_count}") do_something(nums[i]) end
end # better: much more readable
def handle(nums) nums.each_with_index do |num, i| Rails.logger.info("Handling item #{i}/#{nums.count}") do_something(num) end
end

partition

Hãy tưởng tượng bạn có thể chia một mảng thành hai mảng, dựa trên một điều kiện. Bạn có thể làm chính xác điều đó với phân vùng:

# ok: let's split an array to an odd array and even array
def split_odds_evens(nums) odds = [] evens = [] nums.each do |num| if num.odd? odds << num else evens << num end end [odds, evens]
end # better: ruby helps you out! So simple, just inline it
def odd_even_short(nums) nums.partition(&:odd?)
end

select/reject

select lặp lại trên một liệt kê và chỉ trả về các phần tử trả về cho block đã cho. từ chối các hành động giống nhau nhưng ngược lại, nó trả về những hành động không thỏa mãn điều kiện:

### select ###
# ok: get a new array with only odd numbers
def only_odds(nums) result = [] nums.each do |num| result << num if num.odd? end result
end # better: shorter and cleaner
def only_odds_object(nums) nums.each_with_object([]) do |num, arr| arr << num if num.odd? end
end # best: so simple you can just inline it
def only_odds_simple(nums) nums.select(&:odd?)
end ### reject ###
# exact opposite of `select`
def only_odds(nums) nums.reject(&:even?)
end

Đối với mảng, select and reject có sẵn ! : select! và reject!, điều này sẽ sửa đổi kiểu liệt kê đã cho.

any?/all?

any? kiểm tra xem ít nhất một phần tử trong một kiểu liệt kê tương ứng với một điều kiện. all? xác minh rằng tất cả các yếu tố đều phù hợp với điều kiện.

### all? ###
# ok: checking if all nums are odd
def all_odds?(nums) nums.each do |num| return false if num.even? end true
end # better: so simple you don't even really need a method, just inline it
def easier_all_odds?(nums) nums.all?(&:odd?)
end ### any? ###
# ok: checking if any of the numbers are greater than 0
def any_greater_than?(nums, x) nums.each do |num| return true if num > x end return false
end # better: so simple, it might be better to just write it inline
def easier_any_greater_than?(nums, x) nums.any? { |num| num > x }
end

Bình luận

Bài viết tương tự

- vừa được xem lúc

Tổng hợp gem thông dụng trong Rails - Phần 2: Faker và Friendly Id

Ở phần này mình sẽ giới thiệu 2 gems rất quen thuộc với Ruby developers và hơn nữa, mình nghĩ đây cũng là những gem sẽ giúp ích cho các bạn newbies trong quá trình học Ruby on Rails. I. Gem Faker. 1.

0 0 96

- vừa được xem lúc

Gem paper_trail

1. Introduce. . Gem paper_trail được dùng để tracking sự thay đổi của model object và chia thành các version khác nhau.

0 0 40

- vừa được xem lúc

How to drop a table in Ruby

Issue. Với những dự án mới hoặc những dự án nhỏ tự làm, hầu hết bạn sẽ phải thường xuyên thay đổi cấu trúc DB dẫn tới việc phải thực hiện các câu lệnh như rails db:drop db:create db:migrate khá nhiều lần.

0 0 29

- vừa được xem lúc

Một số tips giúp ứng dụng Ruby on Rails bảo mật hơn

Tổng quan. Các Web framework ra đời giúp cho các lập trình viên phát triển các ứng dụng web một cách nhanh chóng và tiện lợi.

0 0 93

- vừa được xem lúc

Rails bundler

1. Introduce. . Một trong những command được sử dụng nhiều nhất khi làm việc với Rails có lẽ là bundle install =)).

0 0 39

- vừa được xem lúc

Tổng hợp gem thông dụng trong Rails - Phần 1: Kaminari và Paranoia

Giới thiệu. Mục đích là để làm một seri blogs tập hợp tất cả những gem gần gũi, thường gặp nhất trong các dự án Rails.

0 0 96