Convert a Hash into an Array

  • Thread starter Eustaquio Rangel de Oliveira Jr.
  • Start date
E

Eustaquio Rangel de Oliveira Jr.

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi!

If I have:

h = {"a"=>"111","b"=>"222"}
h.to_a
=> [["a", "111"], ["b", "222"]]

is there a method to convert a Hash into a "plain" Array like

["a","111","b","222"]

Thanks!

- ----------------------------
Eustáquio "TaQ" Rangel
(e-mail address removed)
http://beam.to/taq
Usuário GNU/Linux no. 224050
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.7 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFB9WJib6UiZnhJiLsRAlZJAKC3n+pmVAsm3qLxWG5li9BDOh2IGQCff8m3
LsYXA0CuhQt/zejSKvSJbmM=
=b4wV
-----END PGP SIGNATURE-----
 
M

Michael Neumann

Eustaquio said:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi!

If I have:

h = {"a"=>"111","b"=>"222"}
h.to_a
=> [["a", "111"], ["b", "222"]]

is there a method to convert a Hash into a "plain" Array like

h.to_a.flatten will do the trick.

Regards,

Michael
 
E

Eustaquio Rangel de Oliveira Jr.

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Michael Neumann wrote:

Hi Michael!

| h.to_a.flatten will do the trick.

THANK you very much! :)

- ----------------------------
Eustáquio "TaQ" Rangel
(e-mail address removed)
http://beam.to/taq
Usuário GNU/Linux no. 224050
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.7 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFB9WU/b6UiZnhJiLsRAqZ2AKCVcApOvbi8qTBh3+H9L8PcmJ8duQCgoSsa
ogE6MAn8QflWy8ZJnqufNkg=
=iJ3K
-----END PGP SIGNATURE-----
 
D

David A. Black

Hi --

Eustaquio said:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi!

If I have:

h = {"a"=>"111","b"=>"222"}
h.to_a
=> [["a", "111"], ["b", "222"]]

is there a method to convert a Hash into a "plain" Array like

h.to_a.flatten will do the trick.

However, if any of the hash values are arrays, they'll get flattened
too:

{ "a" => [1,2,3] }.to_a.flatten # => ["a",1,2,3]

unless of course you do:

require 'flattenx' # from RAA
{ "a" => [1,2,3] }.to_a.flatten_by(1) # => ["a",[1,2,3]]

:)


David
 
R

Robert Klemme

David A. Black said:
Hi --

Eustaquio said:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi!

If I have:

h = {"a"=>"111","b"=>"222"}
h.to_a
=> [["a", "111"], ["b", "222"]]

is there a method to convert a Hash into a "plain" Array like

h.to_a.flatten will do the trick.

However, if any of the hash values are arrays, they'll get flattened
too:

{ "a" => [1,2,3] }.to_a.flatten # => ["a",1,2,3]

unless of course you do:

require 'flattenx' # from RAA
{ "a" => [1,2,3] }.to_a.flatten_by(1) # => ["a",[1,2,3]]

:)

.... or use #inject which also has the advantage of saving the intermediate
array which is created by Hash#to_a:
h = {"a"=>"111","b"=>"222"} => {"a"=>"111", "b"=>"222"}
h.inject([]){|a,(k,v)| a << k << v}
=> ["a", "111", "b", "222"]

Btw, did I mention that I love #inject? :)

Kind regards

robert
 
P

Pit Capitain

Richard said:
Cool! I was wondering how to convert a hash to an array, dropping the
keys in the process. I see that inject does the job nicely. Is there
another way too?

h.inject([]){|a, (k, v)| a << v}

=> ["111", "222"]

h = {"a"=>"111", "b"=>"222"}
p h.values # => ["111", "222"]

Regards,
Pit
 
R

Richard Turner

h = {"a"=>"111", "b"=>"222"}
p h.values # => ["111", "222"]

Even better! I thought there must be a method for that but my (very
quick) search last night didn't find it. Thanks

Richard.
 
L

linus sellberg

georgesawyer said:
(Wistfully) Even though 'inject' is the name in Smalltalk, I feel it were
better named, 'consolidate'.

I don't have anything against #inject, but I could see the case for an
alias #accumulate, much like SICP's accumulate which afaik is the same
thing.

(I wouldn't mind #reduce as well, though that would be slightly incorrect)
 
G

gabriele renzi

linus sellberg ha scritto:
I don't have anything against #inject, but I could see the case for an
alias #accumulate, much like SICP's accumulate which afaik is the same
thing.

(I wouldn't mind #reduce as well, though that would be slightly incorrect)

#fold would be better imho (even if slightly incorrect)
 
A

Alexander Kellett

I lack some comfort with 'inject', even after time: perhaps because it
asks us to pass the code for collapsing (an array of) objects, instead
of
asking the objects to know how to collapse themselves: a known
object-programming principle. Collapse perhaps should be a module
method
of no arguments, mix-inable to any class of objects having the '[]'
method.

the main problem i've had with inject is the naming.
to me it says 'destructive'. and thusly i'd expect
the receiver and the argument to be exactly the other
way around. however swapping them makes no sense as
it forces the use of another temporary. thusly a
change in name should be made :)

haven't heard any better alternative yet however :/

Alex
 
R

Robert Klemme

Alexander Kellett said:
I lack some comfort with 'inject', even after time: perhaps because it
asks us to pass the code for collapsing (an array of) objects, instead of
asking the objects to know how to collapse themselves: a known
object-programming principle. Collapse perhaps should be a module method
of no arguments, mix-inable to any class of objects having the '[]'
method.

the main problem i've had with inject is the naming.
to me it says 'destructive'. and thusly i'd expect
the receiver and the argument to be exactly the other
way around. however swapping them makes no sense as
it forces the use of another temporary. thusly a
change in name should be made :)

haven't heard any better alternative yet however :/

#accum is the only name that fits slightly better than #inject although I'm
sure one can come up with misinterpretations of that name also. Anyway:
#inject is quite complex so it takes some time to get used to the behavior
regardless of how it's named.

<rant>
But: the search for a better name is wasted time IMHO. Things are like they
are and changes to base classes generally do far more harm than good (if
something is seriously flawed that's another story of course).
</rant>

Kind regards

robert
 
P

Phrogz

Robert said:
Alexander Kellett said:
the main problem i've had with inject is the naming.
to me it says 'destructive'. [...]
#accum is the only name that fits slightly better than #inject although I'm
sure one can come up with misinterpretations of that name also. Anyway:
#inject is quite complex so it takes some time to get used to the behavior
regardless of how it's named.

<rant>
But: the search for a better name is wasted time IMHO. Things are like they
are and changes to base classes generally do far more harm than good (if
something is seriously flawed that's another story of course).
</rant>

I respectfully disagree. I was SURE from the name that it must be some
function to modify the original array, inserting new entries. It took
me a long time to understand what it was for.

Obviously we can't ditch the old name (for backwards-compatibility
reasons) but a better alias that is promoted to new users would be a
good idea, IMHO.

How about #each_with_state for a name? #accumulate (or #accum) is not a
bad name, but also implies to me that the result will be the
sum/product/concatenation of values. How would #accum fit for the ri
example of using #inject to find the longest item in a list, for
example? Some form of accumulation is one of the more common uses of
#inject (I gather) but by no means the only use.


Aside - whatever the name, what an excellent, versatile function! For
example, the linked-to geometric series sum at
http://www.brpreiss.com/books/opus8/programs/pgm02_06.txt can be
written in a more terse and (IMO) more ruby-esque way as simply:

def geometric_series_sum( x, n )
(0..n).inject(0){ |sum,i| sum+x**i }
end
 
E

ES

Derek said:
| I respectfully disagree. I was SURE from the name that it must be some
| function to modify the original array, inserting new entries. It took
| me a long time to understand what it was for.
|
| Obviously we can't ditch the old name (for backwards-compatibility
| reasons) but a better alias that is promoted to new users would be a
| good idea, IMHO.
|
| How about #each_with_state for a name? #accumulate (or #accum) is not a
| bad name, but also implies to me that the result will be the
| sum/product/concatenation of values. How would #accum fit for the ri
| example of using #inject to find the longest item in a list, for
| example? Some form of accumulation is one of the more common uses of
| #inject (I gather) but by no means the only use.

Is not #reduce the name we're looking for? Or is it not faithful enough
to lisp to rip off the name?

I'm convinced there were two main creators for Lisp. One designed the
language, and the other one (who, incidentally, was an insane monkey),
came up with the function names.

There's really no perfect name for this method...I'm partial to #fold
after Haskell & Co. but #accum (without the -ate) may describe it's
function the best. Then again, this is just wishful thinking.

E
 
R

Robert Klemme

ES said:
I'm convinced there were two main creators for Lisp. One designed the
language, and the other one (who, incidentally, was an insane monkey),
came up with the function names.

There's really no perfect name for this method...I'm partial to #fold
after Haskell & Co. but #accum (without the -ate) may describe it's
function the best. Then again, this is just wishful thinking.

#aggregate might be a good choice, too - reminds me of SQL aggregation
functions like SUM, AVG, MAX etc.

Kind regards

robert
 
G

Gavri Fernandez

#aggregate might be a good choice, too - reminds me of SQL aggregation
functions like SUM, AVG, MAX etc.

Perfect! I'm surprised no-one thought of this before!

+1 from me
 
M

Mathieu Bouchard

Aside - whatever the name, what an excellent, versatile function! For
example, the linked-to geometric series sum at
http://www.brpreiss.com/books/opus8/programs/pgm02_06.txt can be
written in a more terse and (IMO) more ruby-esque way as simply:
def geometric_series_sum( x, n )
(0..n).inject(0){ |sum,i| sum+x**i }
end

And even shorter,

def geometric_series_sum(x,n) (x**(n+1)-1)/(x-1) end

_____________________________________________________________________
Mathieu Bouchard -=- Montréal QC Canada -=- http://artengine.ca/matju
 
R

Robert Klemme

Mathieu Bouchard said:
And even shorter,

def geometric_series_sum(x,n) (x**(n+1)-1)/(x-1) end

LOL ... and more efficient also. Know your math. :)

Cheers

robert
 
G

Guillaume Marcais

Mathieu Bouchard said:
And even shorter,

def geometric_series_sum(x,n) (x**(n+1)-1)/(x-1) end

To be very picky:

def geometric_series_sum(x,n) (x==1) ? n+1 : (x**(n+1)-1)/(x-1) end

But given how good the original implementation is (it calculates the
power with a loop, restarting from 1 for every n...), almost anything
is an improvement.

Guillaume.
 

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

Similar Threads

%w 3
Asyn sockets 6
Hello guys ! How do I convert a string from an array into numbers ? Javascript 3
Garbage collector 8
Resizing bitmaps 1
Doubt about GC 6
Immediate values 23
convert an array to a hash 6

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top