10055

Ternary operator

Question:

I have an array d = ['foo', 'bar', 'baz'], and want to put its elements together into a string delimited by , and <em>and</em> at the last element so that it will become foo, bar and baz.

Here is what I'm trying to do:

s = '' d.each_with_index { |x,i| s << x s << i < d.length - 1? i == d.length - 2 ? ' and ' : ', ' : '' }

but the interpreter gives an error:

`<': comparison of String with 2 failed (ArgumentError)

However, it works with += instead of <<, but the Ruby Cookbook says that:

<blockquote>

If efficiency is important to you, don't build a new string when you can append items onto an existing string. [And so on]... Use <em>str << var1 << ' ' << var2</em> instead.

</blockquote>

<strong>Is it possible without += in this case?</strong>

Also, there has to be a more elegant way of doing this than the code above.

Answer1:

You're just missing some parenthesis:

d = ['foo', 'bar', 'baz'] s = '' d.each_with_index { |x,i| s << x s << (i < d.length - 1? (i == d.length - 2 ? ' and ' : ', ') : '') }

Answer2:

I'd find

s << i < d.length - 1? i == d.length - 2 ? ' and ' : ', ' : ''

hard to read or maintain.

I'd probably change it to

join = case when i < d.length - 2 then ", " when i == d.length - 2 then " and " when i == d.length then "" end s << join

Or possibly do

earlier_elements = d[0..-2].join(", ") s = [earlier_elements, d[-1..-1]].join(" and ")

Or

joins = [", "] * (d.length - 2) + [" and "] s = d.zip(joins).map(&:join).join

Answer3:

So much simpler like this:

"#{d[0...-1].join(", ")} and #{d.last}"

Recommend

  • Python ctypes: pass argument by reference error
  • Run JUnit Test from a java web application
  • Python: Cross-platform solution to detect physical non-HT CPUs?
  • How can I override the .. and … operators of Ruby Ranges to accept Float::INFINITY?
  • Issues with rails4 and mongoid on production mode
  • How to select a specific field additionally to a tables default fields?
  • ActiveRecord: abort datetime parsing if value is invalid
  • Symfony 3.0 - Cannot load resource “.” - Custom Route Loader
  • Why is new Number(8) not exactly equal to 8?
  • What is the difference between Socket.Send and Stream.Write? (in relation to tcp ip connections)
  • Concise regex extract function in XSLT 2.0
  • How do I capture a rsolr Sunspot exception raised on a different thread from a model callback?
  • SSL client cert authentication for only some URLs?
  • apply a javascript function to draggable copy
  • What causes the runtime difference in this trivial fortran code?
  • VSCode change debug shell to bash on windows
  • Android changing fragment order inside FragmentPagerAdapter
  • ListItem.Attributes.Add not working
  • Problems installing Yesod for Haskell
  • Unable to install Git-core+svn by MacPorts
  • Parse a date string in a specific locale (not timezone!)
  • Create DicomImage from scratch using Dcmtk
  • Groovy: Unexpected token “:”
  • VSO Build — Response status code does not indicate success: 404 (Not Found)
  • Is it possible to access block's scope in method?
  • ilmerge with a PFX file
  • How to recover from a Spring Social ExpiredAuthorizationException
  • ILMerge & Keep Assembly Name
  • How to handle AllServersUnavailable Exception
  • Large data - storage and query
  • WOWZA + RTMP + HTML5 Playback?
  • 0x202A in filename: Why?
  • AT Commands to Send SMS not working in Windows 8.1
  • php design question - will a Helper help here?
  • Windows forms listbox.selecteditem displaying “System.Data.DataRowView” instead of actual value
  • apache spark aggregate function using min value
  • Sorting a 2D array using the second column C++
  • Python/Django TangoWithDjango Models and Databases
  • jQuery Masonry / Isotope and fluid images: Momentary overlap on window resize
  • How do I use LINQ to get all the Items that have a particular SubItem?