"David A. Black" <dblack@wobblini.net> schrieb im Newsbeitrag
news:Pine.LNX.4.61.0501241746590.31348@wobblini...
Hi --
> Eustaquio Rangel de Oliveira Jr. wrote:
>> -----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"]
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"]
Cheers,
Richard.
···
On Tue, 2005-01-25 at 17:10 +0900, Robert Klemme wrote:
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"]
More fundamentally, I suggest 'collapse', because the most general concept
seems of collapsing away one dimension from a multi-dimensional thing.
Notwithstanding that the method should allow, perhaps, a scalar argument,
or no arguments. Pushing the concept to all dimensions would be done
instead first by flatten'ing, then by inject'ing (collapse'ing). Reducing
the dimensionality by one seems useful: here and there, I seem to have
heard of it.
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.
···
linus sellberg <sellberg@google.com> Jan 28, 2005 at 02:12 PM wrote:
georgesawyer wrote:
"Robert Klemme" <bob.news@gmx.net> Jan 25, 2005 at 09:09 AM wrote:
did I mention that I love #inject?
(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
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
···
On Jan 28, 2005, at 7:00 PM, georgesawyer wrote:
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.
"Alexander Kellett" <ruby-lists@lypanov.net> schrieb im Newsbeitrag news:9b411145f76db3c8a017a89ebb9d5611@lypanov.net...
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>
"Alexander Kellett" <ruby-lists@lypanov.net> schrieb im Newsbeitrag
news:9b411145f76db3c8a017a89ebb9d5611@lypanov.net...
> 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 brpreiss.com 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
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?
def geometric_series_sum(x,n) (x**(n+1)-1)/(x-1) end
···
On Fri, 18 Mar 2005, Phrogz wrote:
Aside - whatever the name, what an excellent, versatile function! For
example, the linked-to geometric series sum at brpreiss.com 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
> 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.
The point with #inject was to be faithful to Smalltalk, which uses that
name. Again, I am sorry for having recommended #inject.
In GridFlow (my biggest Ruby library), that thing is called #fold. I guess
I must have taken the name from Haskell. To me it's more
meaningful-sounding than reduce, but your mileage may vary.
···
On Fri, 18 Mar 2005, Derek Wyatt wrote:
> 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?
"Mathieu Bouchard" <matju@sympatico.ca> schrieb im Newsbeitrag news:Pine.LNX.4.21.0503262110380.5161-100000@mondrian.artengine.ca...
Aside - whatever the name, what an excellent, versatile function! For
example, the linked-to geometric series sum at brpreiss.com 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