From: Robert Klemme Date: 2009-12-11T18:14:40+09:00 Subject: Re: human-readable listing of array elements 2009/12/11 w_a_x_man : > On Dec 10, 8:36 am, Robert Klemme wrote: >> 2009/12/10 Aldric Giacomoni : >> >> > This took me less than a minute to write, but I don't know if it's as >> > elegant as it could be. Are there more "Ruby-like ways(tm)" to write >> > this? >> >> > def stringify array >> >  return array[0] if array.size == 1 >> >  string = "" >> >  array.each_with_index do |element, index| >> >    case index >> >      when array.size - 1 # last item >> >        string += " and #{element}" >> >      when 0 >> >        string += "#{element}" >> >      else >> >        string += ", #{element}" >> >    end >> >  end >> >  string >> > end >> >> By using String#<< your code will become more efficient because you do >> not create new String objects all the time. >> >> For the fun of it here are two other solutions: >> >> irb(main):026:0> def stringify array >> irb(main):027:1>   lead = array.slice 0...-1 >> irb(main):028:1>   lead.empty? ? array.last.to_s : [lead.join(", "), >> array.last].join(" and ") >> irb(main):029:1> end >> => nil >> irb(main):031:0> stringify [] >> => "" >> irb(main):032:0> stringify %w{foo} >> => "foo" >> irb(main):033:0> stringify %w{foo bar} >> => "foo and bar" >> irb(main):034:0> stringify %w{foo bar baz} >> => "foo, bar and baz" >> >> irb(main):039:0> def stringify array >> irb(main):040:1>   tail = array.slice -2..-1 >> irb(main):041:1>   tail ? (array.slice(0...-2) << tail.join(" and >> ")).join(", ") : array.first.to_s >> irb(main):042:1> end >> >> irb(main):048:0> stringify [] >> => "" >> irb(main):045:0> stringify %w{foo} >> => "foo" >> irb(main):046:0> stringify %w{foo bar} >> => "foo and bar" >> irb(main):047:0> stringify %w{foo bar baz} >> => "foo, bar and baz" >> >> Note, I don't claim that this is necessarily more rubyish. :-) >> >> Kind regards >> >> robert >> >> -- >> remember.guy do |as, often| as.you_can - without endhttp://blog.rubybestpractices.com/ > > Sometimes it's fun to avoid using conditionals (including > "... ? ... : ...") > when programming. Here's one way that completely gets rid of case and if. :-) ALG = Hash.new( lambda {|a| [a[0...-1].join(", "), a[-1]].join(" and ")} ).merge( 0 => lambda {|a| ""}, 1 => lambda {|a| a.first.to_s}, 2 => lambda {|a| a.join " and "} ) def s(a) ALG[a.size][a] end arr = [] 5.times do |i| p arr, s(arr) arr << "foo#{i}" end > def to_string ary >  a = ary.dup >  a.push( a.pop(2).join " and " ).join ", " > end Nice! Cheers robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/