| |
Dondo Land
Bryan Donovan's Weblog
Sunday August 27, 2006 |
|
Rubyquiz has accepted my submission, asking readers to write a class that returns a range of days in a human-readable format. The quiz can be found here.
Here's an excerpt explaining the idea..
If you've ever created a web application that deals with scheduling recurring events, you may have found yourself creating a method to convert a list of days into a more human-readable string.
For example, suppose a musician plays at a certain venue on Monday, Tuesday, Wednesday, and Saturday. You could pass a list of associated day numbers to your object or method, which might return "Mon-Wed, Sat".
The purpose of this quiz is to find the best "Ruby way" to generate this sentence-like string.
[...]
Here are some example lists of days and their expected returned strings:
1,2,3,4,5,6,7: Mon-Sun
1,2,3,6,7: Mon-Wed, Sat, Sun
1,3,4,5,6: Mon, Wed-Sat
2,3,4,6,7: Tue-Thu, Sat, Sun
1,3,4,6,7: Mon, Wed, Thu, Sat, Sun
7: Sun
1,7: Mon, Sun
1,8: ArgumentError
To my surprise, there have already been several submissions with varying ways of solving the problem. This is a good way to learn some Ruby for sure..
(2006-08-27 12:10:46.0/2006-08-27 10:15:06.0)
Permalink
Trackback: http://blogs.sun.com/bdonovan/entry/day_range_rubyquiz
|
|
|
Trackback URL: http://blogs.sun.com/bdonovan/entry/day_range_rubyquiz
|
| « November 2009 | | Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|
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 | | | | | | | | | | | | | | | Today |
Today's Page Hits: 5
|
class DateRange @@WEEK_DAYS = (1..7) @@DAY_TO_S = %w{zero Mon Tue Wed Thu Fri Sat Sun} @@DAY_TO_I = @@DAY_TO_S.inject(Hash.new) { |h, day| h[day] = h.size; h } def initialize(*days) @day_nums = [] days.each do |day| day = @@DAY_TO_I[day[0..2].capitalize] if day.kind_of?(String) raise ArgumentError unless @@WEEK_DAYS.include?(day) @day_nums.push(day) end @day_nums.sort! end def to_s s = '' days = @day_nums.clone 1.upto(@day_nums.size-1) do |i| today = @day_nums[i] days[i] = nil if @day_nums[i-1] == today-1 and @day_nums[i+1] == today+1 end days.each do |day| s += (day ? ', ' : '-') if s.size > 0 and s[-1].chr != '-' s += @@DAY_TO_S[day] if day end s endPosted by Kevin Hutchinson on August 27, 2006 at 01:42 PM PDT #
Posted by Kevin Hutchinson on August 27, 2006 at 01:45 PM PDT #
Posted by Kevin Hutchinson on August 28, 2006 at 11:02 AM PDT #
class DayRange def day_hash { '1'=>'Mon', '2'=>'Tue', '3'=>'Wed', '4'=>'Thu', '5'=>'Fri', '6'=>'Sat', '7'=>'Sun' } end def initialize(day_ids) @day_ids = day_ids.uniq.sort unless @day_ids.all? { |d| d.between?(1,7) } raise ArgumentError "Days must be between 1 and 7" end end #Returns formatted string representing the day array def to_s day_abbrs = day_hash i = 0 #Array of consed_days arrays consec_day_groups = [] #Array of consecutive days. This gets #reset when we find a day that is not #part of a consecutive set of days. consec_days = [] @day_ids.each do |day_id| if i == 0 #add the day abbr for this day if this is the first #element of @day_ids. consec_days << day_abbrs[day_id.to_s] elsif @day_ids[i-1] == (day_id - 1) #if this is not the first day in @day_ids, check #if the previous day in the array is the real life #previous day of the week. If so, add it to the #consec_days array consec_days << day_abbrs[day_id.to_s] else #otherwise start a new consec_days array and #add the current consec_days array to the #consec_day_groups array. consec_day_groups << consec_days consec_days = [] consec_days << day_abbrs[day_id.to_s] end #Always add the consec_days array when this is the #last day of the @day_ids array if day_id == @day_ids.last consec_day_groups << consec_days end i += 1 end day_strings = [] consec_day_groups.each do |c| if c.length > 2 day_strings << c.first.to_s + "-" + c.last.to_s else day_strings << c.join(", ") end end return day_strings.join(", ") end endPosted by BryanDonovan on August 28, 2006 at 07:02 PM PDT #
As an "old school" Perl programmer, I've been trying to get into Ruby for the past year but I never found a "bite at a time" approach like this. I found it really interesting, and plan to use your Ruby Quiz link to get into Ruby some more. I really hope that scripting in general becomes more popular at Sun because it can be so powerful compared to Java. I know that Mustang will include script support and that's good. But imagine if you could completely script Aquarium (JEE) using Groovy or JRuby? Wow, now you'd be competing with Rails - which for all its sins, gets the job done, and will a huge amount of default usability built in.
What I like about your solution is:
Posted by Kevin Hutchinson on August 29, 2006 at 01:11 PM PDT #
Posted by Bryan on August 29, 2006 at 01:22 PM PDT #