opposite of [thing].flatten

P

Phlip

Ruby-ists:

We all know this clever idiom to turn a variable that might be an Array into
one known to be an Array:

thing = [thing].flatten

That saves a lot of if statements to permit thing's type to overload.

What is the opposite (clever) operation? How to turn a list of one item into
one item, and a list of zero items into nil, but pass thru the list of many
items?
 
P

Philip Hallstrom

Ruby-ists:
We all know this clever idiom to turn a variable that might be an Array into
one known to be an Array:

thing = [thing].flatten

That saves a lot of if statements to permit thing's type to overload.

What is the opposite (clever) operation? How to turn a list of one item into
one item, and a list of zero items into nil, but pass thru the list of many
items?

This almost gets there...

irb(main):006:0> [[]].first
=> []
irb(main):007:0> [["one","two"]].first
=> ["one", "two"]
irb(main):008:0> ["one"].first
=> "one"
 
B

Bill Kelly

From: "Phlip said:
We all know this clever idiom to turn a variable that might be an Array into
one known to be an Array:

thing = [thing].flatten

That saves a lot of if statements to permit thing's type to overload.

What is the opposite (clever) operation? How to turn a list of one item into
one item, and a list of zero items into nil, but pass thru the list of many
items?

Maybe:

irb(main):065:0> x = *[1,2,3]
=> [1, 2, 3]
irb(main):066:0> x = *[1]
=> 1
irb(main):067:0> x = *[]
=> nil


Regards,

Bill
 
R

Rob Biedenharn

Ruby-ists:

We all know this clever idiom to turn a variable that might be an
Array into
one known to be an Array:

thing = [thing].flatten

That saves a lot of if statements to permit thing's type to overload.

What is the opposite (clever) operation? How to turn a list of one
item into
one item, and a list of zero items into nil, but pass thru the list
of many
items?

--
Phlip
http://www.oreilly.com/catalog/9780596510657/
^ assert_xpath
http://tinyurl.com/23tlu5 <-- assert_raise_message

Except for the fact that it is deprecated, use .to_a:

irb(main):001:0> nil.to_a
=> []
irb(main):002:0> "one".to_a
=> ["one"]
irb(main):003:0> [1,2,3].to_a
=> [1, 2, 3]

------------------------------------------------------------ Object#to_a
obj.to_a -> anArray
------------------------------------------------------------------------
Returns an array representation of _obj_. For objects of class
+Object+ and others that don't explicitly override the method, the
return value is an array containing +self+. However, this latter
behavior will soon be obsolete.

self.to_a #=> -:1: warning: default `to_a' will be
obsolete
"hello".to_a #=> ["hello"]
Time.new.to_a #=> [39, 54, 8, 9, 4, 2003, 3, 99, true, "CDT"]


-Rob

Rob Biedenharn http://agileconsultingllc.com
(e-mail address removed)
 
G

Gregory Brown

Not an answer to your question:

Ruby-ists:

We all know this clever idiom to turn a variable that might be an Array into
one known to be an Array:

thing = [thing].flatten

I think

thing = Array(thing)

is more idiomatic.
Array(nil) => []
Array("foo") => ["foo"]
Array(["foo"]) => ["foo"]
Array([["foo"]])
=> [["foo"]]

It does not accidentally flatten nested arrays, and does not throw a
warning like Object#to_a does
 
P

Phlip

Bill said:
Maybe:

irb(main):065:0> x = *[1,2,3]
=> [1, 2, 3]
irb(main):066:0> x = *[1]
=> 1
irb(main):067:0> x = *[]
=> nil

Ouch. I should'a knowed that!!! Wow. Ouch!

I knew Ruby could do it. I also figured I already knew the operator someone
would suggest.

(And extreme thanks for, uh, reading my question..? ;)
 
P

Phlip

Gregory said:
=> [["foo"]]

It does not accidentally flatten nested arrays, and does not throw a
warning like Object#to_a does

Ruby is a strongly-typed language that permits you to write interfaces that
are as feebly- or strongly-typed (or statically-typed) as you like.

If your interface permits one item or a series of similar items, then those
nested arrays are not "accidentally" flattened, they are deliberately
pushed into your interface's contract.

If flattening that deep array and traversing its elements surprises the
user, then maybe they shouldn't pass arrays in that they convoluted for
some other reason!
 
G

Gregory Brown

Gregory said:
Array([["foo"]])
=> [["foo"]]

It does not accidentally flatten nested arrays, and does not throw a
warning like Object#to_a does

Ruby is a strongly-typed language that permits you to write interfaces that
are as feebly- or strongly-typed (or statically-typed) as you like.

If your interface permits one item or a series of similar items, then those
nested arrays are not "accidentally" flattened, they are deliberately
pushed into your interface's contract.

If flattening that deep array and traversing its elements surprises the
user, then maybe they shouldn't pass arrays in that they convoluted for
some other reason!

You're right, but what you said is:

"We all know this clever idiom to turn a variable that might be an Array into
one known to be an Array:"

That's not what your 'idiom' does. It flattens an array that you
create from a single object. Careful wording is important.
 
D

dblack

Hi --

Gregory said:
Array([["foo"]])
=> [["foo"]]

It does not accidentally flatten nested arrays, and does not throw a
warning like Object#to_a does

Ruby is a strongly-typed language that permits you to write interfaces that
are as feebly- or strongly-typed (or statically-typed) as you like.

If your interface permits one item or a series of similar items, then those
nested arrays are not "accidentally" flattened, they are deliberately
pushed into your interface's contract.

There are certainly cases where the flattening is not accidental, but
it sounds like those aren't the ones Greg was referring to :) It's
really just a question of flattening being greedy and a bit of a
"gotcha" at times. In any case, 1.9 introduces an argument to
flatten, so one can do:

array.flatten(1)

and not have to worry about it.


David

--
* Books:
RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242)
RUBY FOR RAILS (http://www.manning.com/black)
* Ruby/Rails training
& consulting: Ruby Power and Light, LLC (http://www.rubypal.com)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,173
Messages
2,570,938
Members
47,473
Latest member
pioneertraining

Latest Threads

Top