Ở các bài viết trước, chúng ta đã tìm hiểu về String và Array trong Ruby. Ở bài viết lần này, chúng ta tiếp tục tìm hiểu về một số object quan trọng khác của Ruby : math, dates, regular expressions, và hashes.
Math
Giống như hầu hết các ngôn ngữ lập trình, Ruby hỗ trợ một số lượng lớn các phép toán:
1 2 3 4 5 6 7 8 9 | <span class="token operator">></span><span class="token operator">></span> <span class="token number">1</span> <span class="token operator">+</span> <span class="token number">1</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token number">2</span> <span class="token operator">></span><span class="token operator">></span> <span class="token number">2</span> <span class="token operator">-</span> <span class="token number">3</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token operator">-</span><span class="token number">1</span> <span class="token operator">></span><span class="token operator">></span> <span class="token number">2</span> <span class="token operator">*</span> <span class="token number">3</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token number">6</span> <span class="token operator">></span><span class="token operator">></span> <span class="token number">10</span><span class="token operator">/</span><span class="token number">5</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token number">2</span> |
Hãy rất chú ý tới phép chia, vì nó dễ gây nhầm lẫn :
1 2 3 4 5 | <span class="token operator">></span><span class="token operator">></span> <span class="token number">10</span><span class="token operator">/</span><span class="token number">4</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token number">2</span> <span class="token operator">></span><span class="token operator">></span> <span class="token number">2</span><span class="token operator">/</span><span class="token number">3</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token number">0</span> |
Ở đây, Ruby sử dụng phép chia số nguyên. Nếu bạn muốn thực hiện phép chia số thập phân, thì hãy thêm .0 vào tử số hoặc mẫu số.
1 2 3 4 5 | <span class="token operator">></span><span class="token operator">></span> <span class="token number">10</span><span class="token operator">/</span><span class="token number">4.0</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token number">2.5</span> <span class="token operator">></span><span class="token operator">></span> <span class="token number">2</span><span class="token operator">/</span><span class="token number">3.0</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token number">0.6666666666666666</span> |
Có rất nhiều dev, trong đó có cả tôi ưa thích sử dụng irb như một chiếc máy tính đơn giản khi có nhu cầu tính toán. Giao diện có vẻ không đẹp mắt lắm, nhưng nó khá nhanh và mạnh mẽ, với khả năng xác định các biến.
More advanced operations
Ruby cũng hỗ trợ một loạt các phép toán nâng cao thông qua module gọi là Math, với các hàm tiện ích như : constants, roots hay các hàm lượng giác.
1 2 3 4 5 6 7 | <span class="token operator">></span><span class="token operator">></span> <span class="token constant">Math</span><span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token constant">PI</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token number">3.141592653589793</span> <span class="token operator">></span><span class="token operator">></span> <span class="token constant">Math</span><span class="token punctuation">.</span>sqrt<span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token number">1.4142135623730951</span> <span class="token operator">></span><span class="token operator">></span> <span class="token constant">Math</span><span class="token punctuation">.</span>cos<span class="token punctuation">(</span><span class="token number">2</span><span class="token operator">*</span><span class="token constant">Math</span><span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token constant">PI</span><span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token number">1</span> |
Ký hiệu dấu 2 chấm và các chữ được viết hoa (Math::PI) ở bên trên là đặc trưng của module constants.
Ngoài ra, Ruby cũng hỗ trợ một số hàm lượng giác và lũy thừa khác như :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <span class="token operator">></span><span class="token operator">></span> <span class="token constant">Math</span><span class="token punctuation">.</span>log<span class="token punctuation">(</span><span class="token constant">Math</span><span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token constant">E</span><span class="token punctuation">)</span> <span class="token number">1</span> <span class="token operator">></span><span class="token operator">></span> <span class="token constant">Math</span><span class="token punctuation">.</span>log<span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span> <span class="token number">2.302585092994046</span> <span class="token operator">></span><span class="token operator">></span> <span class="token constant">Math</span><span class="token punctuation">.</span>log10<span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span> <span class="token number">1</span> <span class="token operator">></span><span class="token operator">></span> <span class="token constant">Math</span><span class="token punctuation">.</span>log10<span class="token punctuation">(</span><span class="token number">1000000</span><span class="token punctuation">)</span> <span class="token number">6</span> <span class="token operator">></span><span class="token operator">></span> <span class="token constant">Math</span><span class="token punctuation">.</span>log10<span class="token punctuation">(</span><span class="token constant">Math</span><span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token constant">E</span><span class="token punctuation">)</span> <span class="token number">0.4342944819032518</span> <span class="token operator">></span><span class="token operator">></span> <span class="token number">2</span><span class="token operator">*</span><span class="token operator">*</span><span class="token number">3</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token number">8</span> <span class="token operator">></span><span class="token operator">></span> <span class="token constant">Math</span><span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token constant">E</span><span class="token operator">*</span><span class="token operator">*</span><span class="token number">100</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token number">2.6881171418161212e+43</span> |
Bạn có thể tìm hiểu chi tiết hơn về module Math tại đây.
Math to string
Ở các bài viết trước, chúng ta đã tìm hiểu cách convert string thành array (và ngược lại) bầng cách sử dụng split và join. Tương tự, Ruby cũng cho phép chúng ta convert giữa number và string.
Có lẽ cách phổ biến nhất để convert number thành string là sử dụng method to_s (“to string”).
1 2 3 4 | <span class="token operator">></span><span class="token operator">></span> tau <span class="token operator">=</span> <span class="token number">2</span> <span class="token operator">*</span> <span class="token constant">Math</span><span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token constant">PI</span> <span class="token operator">></span><span class="token operator">></span> tau<span class="token punctuation">.</span>to_s <span class="token operator">=</span><span class="token operator">></span> <span class="token string">"6.283185307179586"</span> |
Ngoài ra, còn một số method khác như to_i (“to integer”) and to_f (“to float”).
1 2 3 4 5 | <span class="token operator">></span><span class="token operator">></span> <span class="token string">"6.283185307179586"</span><span class="token punctuation">.</span>to_f <span class="token operator">=</span><span class="token operator">></span> <span class="token number">6.283185307179586</span> <span class="token operator">></span><span class="token operator">></span> <span class="token string">"6"</span><span class="token punctuation">.</span>to_i <span class="token operator">=</span><span class="token operator">></span> <span class="token number">6</span> |
Time
Một object cũng thường xuyên được sử dụng khác đó là Time (Về mặt kỹ thuật thì coi nó là một class). Thông qua tìm hiểu về Time, chúng ta có cơ hội đầu tiên để tìm hiểu về new method, còn được gọi là constructor function là một cách cơ bản của Ruby để tạo object mới.
Từ trước tới nay, chúng ta thường sử dụng dấu nháy hoặc dấu ngoặc để khởi tạo trực tiếp một object mới, thì bây giờ cung ta có thể sử dụng method new để định nghĩa một object mới như string hoặc array…
1 2 3 4 5 | <span class="token operator">></span><span class="token operator">></span> s <span class="token operator">=</span> <span class="token builtin">String</span><span class="token punctuation">.</span><span class="token keyword">new</span><span class="token punctuation">(</span><span class="token string">"A man, a plan, a canal—Panama!"</span><span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token string">"A man, a plan, a canal—Panama!"</span> <span class="token operator">></span><span class="token operator">></span> s<span class="token punctuation">.</span>split<span class="token punctuation">(</span><span class="token string">", "</span><span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">[</span><span class="token string">"A man"</span><span class="token punctuation">,</span> <span class="token string">"a plan"</span><span class="token punctuation">,</span> <span class="token string">"a canal—Panama!"</span><span class="token punctuation">]</span> |
và
1 2 3 4 5 6 | <span class="token operator">></span><span class="token operator">></span> a <span class="token operator">=</span> <span class="token builtin">Array</span><span class="token punctuation">.</span><span class="token keyword">new</span> <span class="token operator">></span><span class="token operator">></span> a <span class="token operator"><</span><span class="token operator"><</span> <span class="token number">3</span> <span class="token operator"><</span><span class="token operator"><</span> <span class="token number">4</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">]</span> <span class="token operator">></span><span class="token operator">></span> a <span class="token operator"><</span><span class="token operator"><</span> <span class="token string">"hello, world!"</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token string">'hello, world!'</span><span class="token punctuation">]</span> |
Không giống như string hay array, chúng ta không thể khởi tạo Time bằng dấu ngoặc hay dấu nháy, mà chúng ta phải sử dụng method new.
1 2 3 | <span class="token operator">></span><span class="token operator">></span> now <span class="token operator">=</span> <span class="token builtin">Time</span><span class="token punctuation">.</span><span class="token keyword">new</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token number">2018</span><span class="token operator">-</span><span class="token number">08</span><span class="token operator">-</span><span class="token number">14</span> <span class="token number">19</span><span class="token punctuation">:</span><span class="token number">18</span><span class="token punctuation">:</span><span class="token number">36</span> <span class="token operator">-</span><span class="token number">0700</span> |
Khi gọi mà không truyền vào đối số nào, Time.new sẽ return về time hiện tại. Ngoài ra, ta cũng có thể sử dụng Time.now để lấy về time hiện tại.
1 2 3 | <span class="token operator">></span><span class="token operator">></span> now <span class="token operator">=</span> <span class="token builtin">Time</span><span class="token punctuation">.</span>now <span class="token operator">=</span><span class="token operator">></span> <span class="token number">2018</span><span class="token operator">-</span><span class="token number">08</span><span class="token operator">-</span><span class="token number">14</span> <span class="token number">19</span><span class="token punctuation">:</span><span class="token number">18</span><span class="token punctuation">:</span><span class="token number">55</span> <span class="token operator">-</span><span class="token number">0700</span> |
Cũng tương tự như các object Ruby khác, object Time cũng hỗ trợ nhiều method khác nhau.
1 2 3 4 5 6 7 8 9 | <span class="token operator">></span><span class="token operator">></span> now<span class="token punctuation">.</span>year <span class="token operator">=</span><span class="token operator">></span> <span class="token number">2018</span> <span class="token operator">></span><span class="token operator">></span> now<span class="token punctuation">.</span>day <span class="token operator">=</span><span class="token operator">></span> <span class="token number">14</span> <span class="token operator">></span><span class="token operator">></span> now<span class="token punctuation">.</span>month <span class="token operator">=</span><span class="token operator">></span> <span class="token number">8</span> <span class="token operator">></span><span class="token operator">></span> now<span class="token punctuation">.</span>hour <span class="token operator">=</span><span class="token operator">></span> <span class="token number">19</span> |
Ta cũng có thể khởi tạo object Time bằng cách truyền vào giá trị date và time cụ thể.
1 2 3 4 5 | <span class="token operator">></span><span class="token operator">></span> moon_landing <span class="token operator">=</span> <span class="token builtin">Time</span><span class="token punctuation">.</span><span class="token keyword">new</span><span class="token punctuation">(</span><span class="token number">1969</span><span class="token punctuation">,</span> <span class="token number">7</span><span class="token punctuation">,</span> <span class="token number">20</span><span class="token punctuation">,</span> <span class="token number">20</span><span class="token punctuation">,</span> <span class="token number">17</span><span class="token punctuation">,</span> <span class="token number">40</span><span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token number">1969</span><span class="token operator">-</span><span class="token number">07</span><span class="token operator">-</span><span class="token number">20</span> <span class="token number">20</span><span class="token punctuation">:</span><span class="token number">17</span><span class="token punctuation">:</span><span class="token number">40</span> <span class="token operator">-</span><span class="token number">0700</span> <span class="token operator">></span><span class="token operator">></span> moon_landing<span class="token punctuation">.</span>day <span class="token operator">=</span><span class="token operator">></span> <span class="token number">20</span> |
Mặc định, Time sẽ sử dụng local time zone, tuy nhiên nó sẽ gây ra sự khác biệt giữa các địa điểm cho nên chúng ta sẽ sử dụng giờ UTC.
1 2 3 | <span class="token operator">></span><span class="token operator">></span> moon_landing <span class="token operator">=</span> <span class="token builtin">Time</span><span class="token punctuation">.</span>utc<span class="token punctuation">(</span><span class="token number">1969</span><span class="token punctuation">,</span> <span class="token number">7</span><span class="token punctuation">,</span> <span class="token number">20</span><span class="token punctuation">,</span> <span class="token number">20</span><span class="token punctuation">,</span> <span class="token number">17</span><span class="token punctuation">,</span> <span class="token number">40</span><span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token number">1969</span><span class="token operator">-</span><span class="token number">07</span><span class="token operator">-</span><span class="token number">20</span> <span class="token number">20</span><span class="token punctuation">:</span><span class="token number">17</span><span class="token punctuation">:</span><span class="token number">40</span> <span class="token constant">UTC</span> |
Cuối cùng, đối với Time, ta cũng có thể thực hiện các phép toán với chúng, ví dụ như phép cộng, trừ…
1 2 3 | <span class="token operator">></span><span class="token operator">></span> now <span class="token operator">-</span> moon_landing <span class="token operator">=</span><span class="token operator">></span> <span class="token number">1548482571.0</span> |
Chúng ta có thể lấy về tên của thứ hiện tại bằng cách tạo một array chưa các ngày trong tuần. Sau đó, dùng wday (weekday) như là index của mảng.
1 2 3 4 | irb<span class="token punctuation">(</span>main<span class="token punctuation">)</span><span class="token punctuation">:</span><span class="token number">016</span><span class="token punctuation">:</span><span class="token number">0</span><span class="token operator">></span> <span class="token constant">DAYNAMES</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"Sunday"</span><span class="token punctuation">,</span> <span class="token string">"Monday"</span><span class="token punctuation">,</span> <span class="token string">"Tuesday"</span><span class="token punctuation">,</span> <span class="token string">"Wednesday"</span><span class="token punctuation">,</span><span class="token string">"Thursday"</span><span class="token punctuation">,</span> <span class="token string">"Friday"</span><span class="token punctuation">,</span> <span class="token string">"Saturday"</span><span class="token punctuation">]</span> irb<span class="token punctuation">(</span>main<span class="token punctuation">)</span><span class="token punctuation">:</span><span class="token number">019</span><span class="token punctuation">:</span><span class="token number">0</span><span class="token operator">></span> <span class="token constant">DAYNAMES</span><span class="token punctuation">[</span><span class="token builtin">Time</span><span class="token punctuation">.</span>now<span class="token punctuation">.</span>wday<span class="token punctuation">]</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token string">"Tuesday"</span> |
Cuối cùng, chúng ta sẽ update lại ứng dụng hello app (dùng Sinatra) để hiển thị ra thông tin ngày trong tuần.
1 2 3 4 5 6 7 8 9 | <span class="token keyword">require</span> <span class="token string">'sinatra'</span> get <span class="token string">'/'</span> <span class="token keyword">do</span> <span class="token constant">DAYNAMES</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"Sunday"</span><span class="token punctuation">,</span> <span class="token string">"Monday"</span><span class="token punctuation">,</span> <span class="token string">"Tuesday"</span><span class="token punctuation">,</span> <span class="token string">"Wednesday"</span><span class="token punctuation">,</span> <span class="token string">"Thursday"</span><span class="token punctuation">,</span> <span class="token string">"Friday"</span><span class="token punctuation">,</span> <span class="token string">"Saturday"</span><span class="token punctuation">]</span> dayname <span class="token operator">=</span> <span class="token constant">DAYNAMES</span><span class="token punctuation">[</span><span class="token builtin">Time</span><span class="token punctuation">.</span>now<span class="token punctuation">.</span>wday<span class="token punctuation">]</span> <span class="token string">"Hello, world! Happy <span class="token interpolation"><span class="token delimiter tag">#{</span>dayname<span class="token delimiter tag">}</span></span>."</span> <span class="token keyword">end</span> |
Regular expressions
Ruby support đầy đủ cho regular expressions, thường được gọi ngắn gọn là regexes hoặc regexps, đây là một ngôn ngữ nhỏ và đầy mạnh mẽ cho việc matching các patterns trong text.
Việc master hoàn toàn regular expressions thì nằm ngoài phạm vi của bài viết này, và có lẽ rất ít người master được nó. Nhưng tin tốt là, có rất nhiều tài liệu về regular expressions để chúng ta có thể tìm hiểu sâu về nó.
Điều quan trọng là bạn nắm được ý tưởng chung về regular expressions và có thể tìm hiểu sâu hơn khi bạn cần dùng tới nó.
Regexes nổi tiếng là rất ngắn gọn và dễ bị lỗi, như lập trình viên nổi tiếng – Jamie Zawinski đã nói:
Đối với một số người, khi họ đối mặt với một vấn đề, họ nghĩ “Ok, tôi sẽ dùng regular expressions để giải quyết”. Và thế là họ gặp phải 2 vấn đề!
Thật may mắn là, tình trạng này được cải thiện rất nhiều bới các ứng dụng web hữu ích như là Rubular nó cho phép chúng ta xây dựng các biểu thức regexes một cách trực quan.
Rubular là web regexes chuyên dụng cho Ruby. Và chúng ta hãy cũng tìm hiểu một số kiến thức cơ bản về regex trong Ruby nhé.
Một regex cơ bản là kiểm tra một chuỗi có match với một pattern cụ thể không. Chúng ta có thể tạo một regex mới bằng cách sử dụng hàm new. Tuy nhiên, chúng ta thường sử dụng ký hiệu /…/ hơn.
Ví dụ dưới đây là regex match với ZIP Code của Mỹ, bao gồm 5 chữ số liên tiếp.
zip_code = /d{5}/
Nếu bạn dùng nhiều regular expressions thì bạn sẽ nhớ cú pháp, tuy nhiên bạn cũng có thể tra cứu tại các tài liệu tham khảo như Rubular.
Và bây giờ chúng ta sẽ xem làm thế nào để biết một string có match với regex hay không. Và chúng ta sẽ dùng method match để kiểm tra.
1 2 3 4 5 | <span class="token operator">></span><span class="token operator">></span> <span class="token string">"no match"</span><span class="token punctuation">.</span>match<span class="token punctuation">(</span>zip_code<span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token keyword">nil</span> <span class="token operator">></span><span class="token operator">></span> <span class="token string">"Beverly Hills 90210"</span><span class="token punctuation">.</span>match<span class="token punctuation">(</span>zip_code<span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token comment">#<MatchData "90210"></span> |
Trong thực tế, ta thường dùng nó trong ngữ cảnh boolean hơn, như sau :
1 2 3 4 | <span class="token operator">></span><span class="token operator">></span> s <span class="token operator">=</span> <span class="token string">"Beverly Hills 90210"</span> <span class="token operator">></span><span class="token operator">></span> puts <span class="token string">"It's got a ZIP code!"</span> <span class="token keyword">if</span> s<span class="token punctuation">.</span>match<span class="token punctuation">(</span>zip_code<span class="token punctuation">)</span> <span class="token string">"It's got a ZIP code!"</span> |
Một hoạt động phổ biến khác đó là việc tạo ra một mảng của tất cả các match. Trước hết chúng ta tạo ra một string dài hơn và chứa 2 zip code.
1 2 3 4 5 | <span class="token operator">></span><span class="token operator">></span> s <span class="token operator">=</span> <span class="token string">"Beverly Hills 90210 was a '90s TV show set in Los Angeles."</span> <span class="token operator">></span><span class="token operator">></span> s <span class="token operator">+</span><span class="token operator">=</span> <span class="token string">" 91125 is another ZIP code in the Los Angeles area."</span> <span class="token operator">=</span><span class="token operator">></span> "<span class="token constant">Beverly</span> <span class="token constant">Hills</span> <span class="token number">90210</span> was a '<span class="token number">90</span>s <span class="token constant">TV</span> show set <span class="token keyword">in</span> <span class="token constant">Los</span> <span class="token constant">Angeles</span><span class="token punctuation">.</span> <span class="token number">91125</span> is another <span class="token constant">ZIP</span> code <span class="token keyword">in</span> the <span class="token constant">Los</span> <span class="token constant">Angeles</span> area<span class="token punctuation">.</span>" |
Để check xem string có match với regex hay không, ta sử dụng method String#scan để tìm ra một mảng các matches.
1 2 3 | <span class="token operator">></span><span class="token operator">></span> s<span class="token punctuation">.</span>scan<span class="token punctuation">(</span>zip_code<span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">[</span><span class="token string">"90210"</span><span class="token punctuation">,</span> <span class="token string">"91125"</span><span class="token punctuation">]</span> |
chúng ta cũng có thể sùng scan để tìm ra tất cả các từ đều là chữ in hoa.
1 2 3 | <span class="token operator">></span><span class="token operator">></span> s<span class="token punctuation">.</span>scan<span class="token punctuation">(</span><span class="token regex">/[A-Z]{2,}/</span><span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">[</span><span class="token string">"TV"</span><span class="token punctuation">,</span> <span class="token string">"ZIP"</span><span class="token punctuation">]</span> |
Ngoài ra, bạn có thể tham khảo thêm ở Rubular .
Splitting on regexes
Ở phần trước, chúng ta đã tìm hiểu cách split một chuỗi dựa trên space như thế này:
1 2 3 | <span class="token operator">></span><span class="token operator">></span> <span class="token string">"ant bat cat duck"</span><span class="token punctuation">.</span>split<span class="token punctuation">(</span><span class="token string">" "</span><span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">[</span><span class="token string">'ant'</span><span class="token punctuation">,</span> <span class="token string">'bat'</span><span class="token punctuation">,</span> <span class="token string">'cat'</span><span class="token punctuation">,</span> <span class="token string">'duck'</span><span class="token punctuation">]</span> |
Ở phần này, bằng cách vận dụng regex chúng ta có thể sử dụng phương pháp mang lại hiệu quả mạnh mẽ hơn. Trong regex thì khoảng trắng là s và thể hiện việc “một hoặc nhiều” là dấu cộng +. Và chúng ta được kết quả như sau:
1 2 3 | <span class="token operator">></span><span class="token operator">></span> <span class="token string">"ant bat cat duck"</span><span class="token punctuation">.</span>split<span class="token punctuation">(</span><span class="token regex">/s+/</span><span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">[</span><span class="token string">"ant"</span><span class="token punctuation">,</span> <span class="token string">"bat"</span><span class="token punctuation">,</span> <span class="token string">"cat"</span><span class="token punctuation">,</span> <span class="token string">"duck"</span><span class="token punctuation">]</span> |
Bằng cách này thì chúng ta sẽ có được kết quả tương tự đối với string có nhiều khoảng trắng, nhiều tabs, hay nhiều newline…
1 2 3 | <span class="token operator">></span><span class="token operator">></span> <span class="token string">"ant battcatnduck"</span><span class="token punctuation">.</span>split<span class="token punctuation">(</span><span class="token regex">/s+/</span><span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">[</span><span class="token string">"ant"</span><span class="token punctuation">,</span> <span class="token string">"bat"</span><span class="token punctuation">,</span> <span class="token string">"cat"</span><span class="token punctuation">,</span> <span class="token string">"duck"</span><span class="token punctuation">]</span> |
Ngoài ra, đã khi gọi hàm split không tham số, thì Ruby cũng tự động phân tách dựa trên khoảng trắng:
1 2 3 | <span class="token operator">></span><span class="token operator">></span> <span class="token string">"ant battcatnduck"</span><span class="token punctuation">.</span>split <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">[</span><span class="token string">"ant"</span><span class="token punctuation">,</span> <span class="token string">"bat"</span><span class="token punctuation">,</span> <span class="token string">"cat"</span><span class="token punctuation">,</span> <span class="token string">"duck"</span><span class="token punctuation">]</span> |
Hashes
Kiểu data tiếp theo chúng ta sẽ tìm hiểu đó là hash hay còn được gọi là associative array (mảng kết hợp). Bạn có thể nghĩ hash giống như một mảng thông thường nhưng nó được gán nhãn cho mỗi giá trị chứ không phải tính theo chỉ số. Ví dụ, Thay vì là array[0] = 0 thì trong hash sẽ là hash[“name”] = “Michael”. Do đó, mỗi phần tử trong đó là một cặp giá trị: bao gồm 1 label (key) và một giá trị bất kỳ (valune). Và ta thường gọi nó là cặp key/value.
Và chúng ta thường set giá trị cho label (key) là kiểu string, ví dụ ta có thể tạo một object lưu họ và tên của user như sau:
1 2 3 4 5 6 7 | <span class="token operator">></span><span class="token operator">></span> user <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token comment"># {} is an empty hash.</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token operator">></span><span class="token operator">></span> user<span class="token punctuation">[</span><span class="token string">"first_name"</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"Michael"</span> <span class="token comment"># Key "first_name", value "Michael"</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token string">"Michael"</span> <span class="token operator">></span><span class="token operator">></span> user<span class="token punctuation">[</span><span class="token string">"last_name"</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"Hartl"</span> <span class="token comment"># Key "last_name", value "Hartl"</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token string">"Hartl"</span> |
Như bạn thấy, ta khởi tạo một empty hash bằng dấu ngoặc nhọn {}. Và gán giá trị cho phần tử bằng dấu ngoặc vuông [] (tương tự như đối với mảng). Và ta có thể truy xuất giá trị của phần tử theo cùng 1 cách:
1 2 3 4 5 6 7 | <span class="token operator">></span><span class="token operator">></span> user<span class="token punctuation">[</span><span class="token string">"first_name"</span><span class="token punctuation">]</span> <span class="token comment"># Element access is like arrays</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token string">"Michael"</span> <span class="token operator">></span><span class="token operator">></span> user<span class="token punctuation">[</span><span class="token string">"last_name"</span><span class="token punctuation">]</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token string">"Hartl"</span> <span class="token operator">></span><span class="token operator">></span> user<span class="token punctuation">[</span><span class="token string">"nonexistent"</span><span class="token punctuation">]</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token keyword">nil</span> |
Lưu ý, ở ví dụ cuối cùng bên trên, hash sẽ trả về nil khi key không tồn tại.
Thay vì định nghĩa từng phần tử một cho hash bằng cách dùng dấu ngoặc vuông, thì ta có thể dùng dấu hashrocket => để định nghĩa một loạt các phần tử.
1 2 3 4 5 | <span class="token operator">></span><span class="token operator">></span> user <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">{</span><span class="token string">"first_name"</span><span class="token operator">=</span><span class="token operator">></span><span class="token string">"Michael"</span><span class="token punctuation">,</span> <span class="token string">"last_name"</span><span class="token operator">=</span><span class="token operator">></span><span class="token string">"Hartl"</span><span class="token punctuation">}</span> <span class="token operator">></span><span class="token operator">></span> moonman <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token string">"first_name"</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token string">"Buzz"</span><span class="token punctuation">,</span> <span class="token string">"last_name"</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token string">"Aldrin"</span> <span class="token punctuation">}</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">{</span><span class="token string">"first_name"</span><span class="token operator">=</span><span class="token operator">></span><span class="token string">"Buzz"</span><span class="token punctuation">,</span> <span class="token string">"last_name"</span><span class="token operator">=</span><span class="token operator">></span><span class="token string">"Aldrin"</span><span class="token punctuation">}</span> |
Symbols
Như đã tìm hiểu ở bên trên, chúng ta đã sử dụng string cho hash key, tuy nhiên hiện tại chúng ta thường sử dụng symbols hơn.
Symbols trông cũng tương tự string, tuy nhiên nó sẽ đi kèm tiền tố là dấu hai chấm :, chứ không phải được bao quanh bằng dấu ngoặc kép.
1 2 3 4 5 | <span class="token operator">></span><span class="token operator">></span> <span class="token string">"name"</span><span class="token punctuation">.</span>split<span class="token punctuation">(</span><span class="token string">''</span><span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">[</span><span class="token string">"n"</span><span class="token punctuation">,</span> <span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token string">"m"</span><span class="token punctuation">,</span> <span class="token string">"e"</span><span class="token punctuation">]</span> <span class="token operator">></span><span class="token operator">></span> <span class="token symbol">:name</span><span class="token punctuation">.</span>split<span class="token punctuation">(</span><span class="token string">''</span><span class="token punctuation">)</span> <span class="token constant">NoMethodError</span><span class="token punctuation">:</span> undefined method `split' <span class="token keyword">for</span> <span class="token symbol">:name</span><span class="token symbol">:Symbol</span> |
Symbols là một kiểu dữ liệu đặc biệt của Ruby, và rất ít có ở các ngôn ngữ khác. Do đó, ban đầu nhìn chúng có vẻ hơi lạ, nhưng Ruby sử dụng chúng rất nhiều, nên bạn sẽ nhanh chóng làm quen với nó thôi.
Không giống như string, không phải tất cả các ký tự đều hợp lệ đối với symbol, tuy nhiên, nếu bạn để nó trong dấu nháy kép như là một loại string thì nó sẽ chạy:
1 2 3 4 5 6 7 8 9 | <span class="token operator">></span><span class="token operator">></span> <span class="token symbol">:foo</span><span class="token operator">-</span>bar <span class="token constant">NameError</span><span class="token punctuation">:</span> undefined local variable <span class="token keyword">or</span> method `bar' <span class="token keyword">for</span> main<span class="token symbol">:Object</span> <span class="token operator">></span><span class="token operator">></span> <span class="token punctuation">:</span><span class="token number">2</span>foo <span class="token constant">SyntaxError</span> <span class="token operator">></span><span class="token operator">></span> <span class="token punctuation">:</span><span class="token string">"foo-bar"</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">:</span><span class="token string">"foo-bar"</span> <span class="token operator">></span><span class="token operator">></span> <span class="token punctuation">:</span><span class="token string">"2foo"</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">:</span><span class="token string">"2foo"</span> |
Chúng ta có thể định nghĩa một hash user sử dụng symbol như sau:
1 2 3 4 5 6 7 | <span class="token operator">></span><span class="token operator">></span> user <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token symbol">:name</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token string">"Michael Hartl"</span><span class="token punctuation">,</span> <span class="token symbol">:email</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token string">"<a class="__cf_email__" href="/cdn-cgi/l/email-protection">[email protected]</a>"</span> <span class="token punctuation">}</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">{</span><span class="token symbol">:name</span><span class="token operator">=</span><span class="token operator">></span><span class="token string">"Michael Hartl"</span><span class="token punctuation">,</span> <span class="token symbol">:email</span><span class="token operator">=</span><span class="token operator">></span><span class="token string">"<a class="__cf_email__" href="/cdn-cgi/l/email-protection">[email protected]</a>"</span><span class="token punctuation">}</span> <span class="token operator">></span><span class="token operator">></span> user<span class="token punctuation">[</span><span class="token symbol">:name</span><span class="token punctuation">]</span> <span class="token comment"># Access the value corresponding to :name.</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token string">"Michael Hartl"</span> <span class="token operator">></span><span class="token operator">></span> user<span class="token punctuation">[</span><span class="token symbol">:password</span><span class="token punctuation">]</span> <span class="token comment"># Access the value of an undefined key.</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token keyword">nil</span> |
Việc sử dụng symbol cho hash là rất phổ biển, vì vậy Ruby cũng hỗ trợ cách khởi tạo hash như sau:
1 2 3 | <span class="token operator">></span><span class="token operator">></span> user <span class="token operator">=</span> <span class="token punctuation">{</span> name<span class="token punctuation">:</span> <span class="token string">"Michael Hartl"</span><span class="token punctuation">,</span> email<span class="token punctuation">:</span> <span class="token string">"<a class="__cf_email__" href="/cdn-cgi/l/email-protection">[email protected]</a>"</span> <span class="token punctuation">}</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">{</span><span class="token symbol">:name</span><span class="token operator">=</span><span class="token operator">></span><span class="token string">"Michael Hartl"</span><span class="token punctuation">,</span> <span class="token symbol">:email</span><span class="token operator">=</span><span class="token operator">></span><span class="token string">"<a class="__cf_email__" href="/cdn-cgi/l/email-protection">[email protected]</a>"</span><span class="token punctuation">}</span> |
Ở syntax thứ 2, ta đã thay thế ký hiệu symbol/hashrocket, bằng tên của key và theo sau là dấu 2 chấm.
1 2 | <span class="token punctuation">{</span> name<span class="token punctuation">:</span> <span class="token string">"Michael Hartl"</span><span class="token punctuation">,</span> email<span class="token punctuation">:</span> <span class="token string">"<a class="__cf_email__" href="/cdn-cgi/l/email-protection">[email protected]</a>"</span> <span class="token punctuation">}</span> |
Cách viết này tương tự với các ngôn ngữ khác (như là Javascript) nên cách viết này ngày càng được ưa thích trong cộng đồng Ruby. Tóm lại, 2 cách viết trên là rất phổ biến, cho nên ta có thể viết theo cách nào cũng được.
Tuy nhiên, bạn cần để ý kỹ cách viết khác nhau giữa 2 cách trên để tránh nhầm lẫn, đó là : { :name => "Michael Hartl" }
(dấu 2 chấm đằng trước, và có dấu hashrocket =>) và { name: "Michael Hartl" }
(dấu 2 chấm phía sau)
Nested hashes
Thực ra, hash có thể chưa bất kỳ giá trị gì, thậm trí là chứa các hash khác. Và người ta gọi nó là nested hashes, nó thường xuyên được sử dụng trong phát triển web.
1 2 3 4 5 6 7 8 9 | <span class="token operator">></span><span class="token operator">></span> params <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token comment"># Define a hash called 'params' (short for 'parameters').</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token operator">></span><span class="token operator">></span> params<span class="token punctuation">[</span><span class="token symbol">:user</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">{</span> name<span class="token punctuation">:</span> <span class="token string">"Michael Hartl"</span><span class="token punctuation">,</span> email<span class="token punctuation">:</span> <span class="token string">"<a class="__cf_email__" href="/cdn-cgi/l/email-protection">[email protected]</a>"</span> <span class="token punctuation">}</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">{</span><span class="token symbol">:name</span><span class="token operator">=</span><span class="token operator">></span><span class="token string">"Michael Hartl"</span><span class="token punctuation">,</span> <span class="token symbol">:email</span><span class="token operator">=</span><span class="token operator">></span><span class="token string">"<a class="__cf_email__" href="/cdn-cgi/l/email-protection">[email protected]</a>"</span><span class="token punctuation">}</span> <span class="token operator">></span><span class="token operator">></span> params <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">{</span><span class="token symbol">:user</span><span class="token operator">=</span><span class="token operator">></span><span class="token punctuation">{</span><span class="token symbol">:name</span><span class="token operator">=</span><span class="token operator">></span><span class="token string">"Michael Hartl"</span><span class="token punctuation">,</span> <span class="token symbol">:email</span><span class="token operator">=</span><span class="token operator">></span><span class="token string">"<a class="__cf_email__" href="/cdn-cgi/l/email-protection">[email protected]</a>"</span><span class="token punctuation">}</span><span class="token punctuation">}</span> <span class="token operator">></span><span class="token operator">></span> params<span class="token punctuation">[</span><span class="token symbol">:user</span><span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token symbol">:email</span><span class="token punctuation">]</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token string">"<a class="__cf_email__" href="/cdn-cgi/l/email-protection">[email protected]</a>"</span> |
Hash iteration
Cũng tương tự như array, hash cũng support method each. Ví dụ, hãy xem hash flash với key là :success và :danger
1 2 3 4 5 6 7 8 | <span class="token operator">></span><span class="token operator">></span> flash <span class="token operator">=</span> <span class="token punctuation">{</span> success<span class="token punctuation">:</span> <span class="token string">"It worked!"</span><span class="token punctuation">,</span> danger<span class="token punctuation">:</span> <span class="token string">"It failed."</span> <span class="token punctuation">}</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">{</span><span class="token symbol">:success</span><span class="token operator">=</span><span class="token operator">></span><span class="token string">"It worked!"</span><span class="token punctuation">,</span> <span class="token symbol">:danger</span><span class="token operator">=</span><span class="token operator">></span><span class="token string">"It failed."</span><span class="token punctuation">}</span> <span class="token operator">></span><span class="token operator">></span> flash<span class="token punctuation">.</span><span class="token keyword">each</span> <span class="token keyword">do</span> <span class="token operator">|</span>key<span class="token punctuation">,</span> value<span class="token operator">|</span> <span class="token operator">?</span><span class="token operator">></span> puts <span class="token string">"Key <span class="token interpolation"><span class="token delimiter tag">#{</span>key<span class="token punctuation">.</span>inspect<span class="token delimiter tag">}</span></span> has value <span class="token interpolation"><span class="token delimiter tag">#{</span>value<span class="token punctuation">.</span>inspect<span class="token delimiter tag">}</span></span>"</span> <span class="token operator">></span><span class="token operator">></span> <span class="token keyword">end</span> <span class="token constant">Key</span> <span class="token symbol">:success</span> has value <span class="token string">"It worked!"</span> <span class="token constant">Key</span> <span class="token symbol">:danger</span> has value <span class="token string">"It failed."</span> |
Chú ý rằng, trong khi each trong array thì chỉ có một biến trong block code, thì each trong hash sẽ có 2 biến đó là key và value. Do vậy, với mỗi vòng lặp each method sẽ lặp qua một cặp key-value.
Tiếp theo, ta sẽ tìm hiểu method inspect, hàm này trả về một string với chữ đại diện mà nó gọi:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <span class="token operator">></span><span class="token operator">></span> puts <span class="token punctuation">(</span><span class="token number">1.</span><span class="token number">.5</span><span class="token punctuation">)</span><span class="token punctuation">.</span>to_a <span class="token comment"># Put an array as a string.</span> <span class="token number">1</span> <span class="token number">2</span> <span class="token number">3</span> <span class="token number">4</span> <span class="token number">5</span> <span class="token operator">></span><span class="token operator">></span> puts <span class="token punctuation">(</span><span class="token number">1.</span><span class="token number">.5</span><span class="token punctuation">)</span><span class="token punctuation">.</span>to_a<span class="token punctuation">.</span>inspect <span class="token comment"># Put a literal array.</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span> <span class="token operator">></span><span class="token operator">></span> puts <span class="token symbol">:name</span><span class="token punctuation">,</span> <span class="token symbol">:name</span><span class="token punctuation">.</span>inspect name <span class="token symbol">:name</span> <span class="token operator">></span><span class="token operator">></span> puts <span class="token string">"It worked!"</span><span class="token punctuation">,</span> <span class="token string">"It worked!"</span><span class="token punctuation">.</span>inspect <span class="token constant">It</span> worked<span class="token operator">!</span> <span class="token string">"It worked!"</span> |
Chúng ta có cách viết ngắn gọn của inspect là:
1 2 3 | <span class="token operator">></span><span class="token operator">></span> p <span class="token symbol">:name</span> <span class="token comment"># Same output as 'puts :name.inspect'</span> <span class="token symbol">:name</span> |
Application: unique words
Giờ thì chúng ta sẽ áp dụng kiến thức về hash ở trên và làm thử một bài tập nhé. Nhiệm vụ của chúng ta là trích xuất các từ trong một đoạn văn khá dài, và đếm số lần mà từ đó xuất hiện.
Vì code của chúng ta có vẻ dài, nên ta sẽ tạo một file Ruby để tiện thao tác. Ta có thể tạo file bằng cách gõ lệnh sau:
$ touch count.rb
và khởi tạo một biến chứa string như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | sonnet <span class="token operator">=</span> "<span class="token constant">Let</span> me <span class="token keyword">not</span> to the marriage of <span class="token boolean">true</span> minds <span class="token constant">Admit</span> impediments<span class="token punctuation">.</span> <span class="token constant">Love</span> is <span class="token keyword">not</span> love <span class="token constant">Which</span> alters <span class="token keyword">when</span> it alteration finds<span class="token punctuation">,</span> <span class="token constant">Or</span> bends with the remover to remove<span class="token punctuation">.</span> <span class="token constant">O</span> no<span class="token punctuation">,</span> it is an ever<span class="token operator">-</span>fixed mark <span class="token constant">That</span> looks on tempests <span class="token keyword">and</span> is never shaken <span class="token constant">It</span> is the star to every wand'ring bark<span class="token punctuation">,</span> <span class="token constant">Whose</span> worth's unknown<span class="token punctuation">,</span> although his height be taken<span class="token punctuation">.</span> <span class="token constant">Love</span><span class="token string">'s not time'</span>s fool<span class="token punctuation">,</span> though rosy lips <span class="token keyword">and</span> cheeks <span class="token constant">Within</span> his bending sickle's compass come<span class="token punctuation">:</span> <span class="token constant">Love</span> alters <span class="token keyword">not</span> with his brief hours <span class="token keyword">and</span> weeks<span class="token punctuation">,</span> <span class="token constant">But</span> bears it out even to the edge of doom<span class="token punctuation">.</span> <span class="token constant">If</span> this be error <span class="token keyword">and</span> upon me proved<span class="token punctuation">,</span> <span class="token constant">I</span> never writ<span class="token punctuation">,</span> nor no man ever loved<span class="token punctuation">.</span>" |
Và khởi tạo một hash là uniques chứa những từ duy nhất: uniques = {}
.
Sau đó định nghĩa biến words chứa một hay nhiều từ, sử dụng regular expression: words = sonnet.scan(/w+/)
Và sử dụng scan method để trả về một mảng các string match với regex bên trên.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | sonnet <span class="token operator">=</span> "<span class="token constant">Let</span> me <span class="token keyword">not</span> to the marriage of <span class="token boolean">true</span> minds <span class="token constant">Admit</span> impediments<span class="token punctuation">.</span> <span class="token constant">Love</span> is <span class="token keyword">not</span> love <span class="token constant">Which</span> alters <span class="token keyword">when</span> it alteration finds<span class="token punctuation">,</span> <span class="token constant">Or</span> bends with the remover to remove<span class="token punctuation">.</span> <span class="token constant">O</span> no<span class="token punctuation">,</span> it is an ever<span class="token operator">-</span>fixed mark <span class="token constant">That</span> looks on tempests <span class="token keyword">and</span> is never shaken <span class="token constant">It</span> is the star to every wand'ring bark<span class="token punctuation">,</span> <span class="token constant">Whose</span> worth's unknown<span class="token punctuation">,</span> although his height be taken<span class="token punctuation">.</span> <span class="token constant">Love</span><span class="token string">'s not time'</span>s fool<span class="token punctuation">,</span> though rosy lips <span class="token keyword">and</span> cheeks <span class="token constant">Within</span> his bending sickle's compass come<span class="token punctuation">:</span> <span class="token constant">Love</span> alters <span class="token keyword">not</span> with his brief hours <span class="token keyword">and</span> weeks<span class="token punctuation">,</span> <span class="token constant">But</span> bears it out even to the edge of doom<span class="token punctuation">.</span> <span class="token constant">If</span> this be error <span class="token keyword">and</span> upon me proved<span class="token punctuation">,</span> <span class="token constant">I</span> never writ<span class="token punctuation">,</span> nor no man ever loved<span class="token punctuation">.</span>" uniques <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> words <span class="token operator">=</span> sonnet<span class="token punctuation">.</span>scan<span class="token punctuation">(</span><span class="token regex">/w+/</span><span class="token punctuation">)</span> |
Tiếp theo, chúng ta sẽ lặp qua mảng words và thực hiện những việc sau:
- Nếu từ đó đã tồn tại thì cộng thêm 1
- Nếu từ đó chưa tồn tại thì khởi tạo là 1
Sử dụng toán tử += để thực hiện, như sau:
1 2 3 4 5 6 7 8 | words.each do |word| if uniques[word] uniques[word] += 1 else uniques[word] = 1 end end |
Và cuối cùng là in ra kết quả:puts uniques
Code đầy đủ sẽ như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | sonnet <span class="token operator">=</span> "<span class="token constant">Let</span> me <span class="token keyword">not</span> to the marriage of <span class="token boolean">true</span> minds <span class="token constant">Admit</span> impediments<span class="token punctuation">.</span> <span class="token constant">Love</span> is <span class="token keyword">not</span> love <span class="token constant">Which</span> alters <span class="token keyword">when</span> it alteration finds<span class="token punctuation">,</span> <span class="token constant">Or</span> bends with the remover to remove<span class="token punctuation">.</span> <span class="token constant">O</span> no<span class="token punctuation">,</span> it is an ever<span class="token operator">-</span>fixed mark <span class="token constant">That</span> looks on tempests <span class="token keyword">and</span> is never shaken <span class="token constant">It</span> is the star to every wand'ring bark<span class="token punctuation">,</span> <span class="token constant">Whose</span> worth's unknown<span class="token punctuation">,</span> although his height be taken<span class="token punctuation">.</span> <span class="token constant">Love</span><span class="token string">'s not time'</span>s fool<span class="token punctuation">,</span> though rosy lips <span class="token keyword">and</span> cheeks <span class="token constant">Within</span> his bending sickle's compass come<span class="token punctuation">:</span> <span class="token constant">Love</span> alters <span class="token keyword">not</span> with his brief hours <span class="token keyword">and</span> weeks<span class="token punctuation">,</span> <span class="token constant">But</span> bears it out even to the edge of doom<span class="token punctuation">.</span> <span class="token constant">If</span> this be error <span class="token keyword">and</span> upon me proved<span class="token punctuation">,</span> <span class="token constant">I</span> never writ<span class="token punctuation">,</span> nor no man ever loved<span class="token punctuation">.</span>" <span class="token comment"># Unique words</span> uniques <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token comment"># All words in the text</span> words <span class="token operator">=</span> sonnet<span class="token punctuation">.</span>scan<span class="token punctuation">(</span><span class="token regex">/w+/</span><span class="token punctuation">)</span> <span class="token comment"># Iterate through `words` and build up a hash of unique words.</span> words<span class="token punctuation">.</span><span class="token keyword">each</span> <span class="token keyword">do</span> <span class="token operator">|</span>word<span class="token operator">|</span> <span class="token keyword">if</span> uniques<span class="token punctuation">[</span>word<span class="token punctuation">]</span> uniques<span class="token punctuation">[</span>word<span class="token punctuation">]</span> <span class="token operator">+</span><span class="token operator">=</span> <span class="token number">1</span> <span class="token keyword">else</span> uniques<span class="token punctuation">[</span>word<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">1</span> <span class="token keyword">end</span> <span class="token keyword">end</span> puts uniques |
Thực hiện chạy file count.rb, ta được kết quả như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | $ ruby count<span class="token punctuation">.</span>rb <span class="token punctuation">{</span><span class="token string">"Let"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"me"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token string">"not"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token string">"to"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token string">"the"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token string">"marriage"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"of"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token string">"true"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"minds"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"Admit"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"impediments"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"Love"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token string">"is"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token string">"love"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"Which"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"alters"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token string">"when"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"it"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token string">"alteration"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"finds"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"Or"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"bends"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"with"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token string">"remover"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"remove"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"O"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"no"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token string">"an"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"ever"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token string">"fixed"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"mark"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"That"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"looks"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"on"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"tempests"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"and"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token string">"never"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token string">"shaken"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"It"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"star"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"every"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"wand"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"ring"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"bark"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"Whose"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"worth"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"s"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token string">"unknown"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"although"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"his"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token string">"height"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"be"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token string">"taken"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"time"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"fool"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"though"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"rosy"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"lips"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"cheeks"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"Within"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"bending"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"sickle"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"compass"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"come"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"brief"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"hours"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"weeks"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"But"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"bears"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"out"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"even"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"edge"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"doom"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"If"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"this"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"error"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"upon"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"proved"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"I"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"writ"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"nor"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"man"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"loved"</span><span class="token operator">=</span><span class="token operator">></span><span class="token number">1</span><span class="token punctuation">}</span> |
Hết. Chúng ta sẽ cùng nhau tìm hiểu các chủ đề khác trong Ruby ở các bài viết lần tới nhé.
Nguồn: Learn-enough