How to make an array of hashes to a single array with all thevalues of these hashes ?

K

kazaam

Take a look at this,
puts myvalue.inspect
shows this here:

[{:url=>"http://www.ruby-lang.org/"}, {:url=>"http://www.ruby-lang.org/en/20020101.html"}, {:url=>"http://en.wikipedia.org/wiki/Ruby_programming_language"}, {:url=>"http://en.wikipedia.org/wiki/Ruby"}, {:url=>"http://www.rubyonrails.org/"}, {:url=>"
"}, {:url=>"http://www.rubycentral.org/"}, {:url=>"http://www.zenspider.com/Languages/Ruby/QuickRef.html"}, {:url=>"http://www.rubycentral.com/book/"}, {:url=>"http://poignantguide.net/"}]


That's an array of hashes or? But how to get this to an array of the values of these hashes? Like my_new_array == ["http://www.ruby-lang.org/","http://www.ruby-lang.org/en/20020101.html","http://en.wikipedia.org/wiki/Ruby_programming_language",...].

myvalue.each {|arr| puts arr.values }
gives me:

http://www.ruby-lang.org/
http://www.ruby-lang.org/en/20020101.html
http://en.wikipedia.org/wiki/Ruby_programming_language
http://en.wikipedia.org/wiki/Ruby
http://www.rubyonrails.org/
http://www.rubycentral.org/
http://www.zenspider.com/Languages/Ruby/QuickRef.html
http://www.rubycentral.com/book/
http://poignantguide.net/

what's correct! But I can't save it to an array. Why? I tried
myvalue.each {|arr| @my_new_array << arr.values }
puts @my_new_array
But I just get nil :( ? I can't make an array out of this.
 
P

Phrogz

That's an array of hashes or? But how to get this to an array of the values of these hashes?

Depending on what you want, try either:
my_array.map{ |h| h[:url] }
or
my_array.map{ |h| h.values }.flatten
 
D

dima

That's an array of hashes or? But how to get this to an array of the values of these hashes?

Depending on what you want, try either:
my_array.map{ |h| h[:url] }
or
my_array.map{ |h| h.values }.flatten

The beauty is that you can do the same stuff in so many different
ways ;-)

data = [{:url=>"http://www.ruby-lang.org/"}, {:url=>"http://www.ruby-
lang.org/en/20020101.html"}, {:url=>"http://en.wikipedia.org/wiki/
Ruby_programming_language"}, {:url=>"http://en.wikipedia.org/wiki/
Ruby"}, {:url=>"http://www.rubyonrails.org/"}, {:url=>"http://
www.youtube.com/watch?v=JMDcOViViNY"}, {:url=>"http://
www.rubycentral.org/"}, {:url=>"http://www.zenspider.com/Languages/
Ruby/QuickRef.html"}, {:url=>"http://www.rubycentral.com/book/"},
{:url=>"http://poignantguide.net/"}]

a = []

data.collect do |item|
item.each_value { |value| a << value }
end
 
Y

yermej

The beauty is that you can do the same stuff in so many different
ways ;-)

I'll offer up an inject solution for this one:

my_new_array = myvalue.inject([]) {|arr, h| arr + h.values}

Jeremy
 
K

kazaam

thanks guys! dimas solution showed me my error

myvalue.each {|arr| @my_new_array << arr.values }
puts @my_new_array

is working if I initialize @my_new_array = [] before like dima did with a = [] but two questions:

Why is a local variable my_new_array not working but just @ instance or $ global variables and why do I have
initialize this varriable? I think you don't need this in ruby? But without initialisation it just shows nil?

greets
 
T

Todd Benson

thanks guys! dimas solution showed me my error

myvalue.each {|arr| @my_new_array << arr.values }
puts @my_new_array

is working if I initialize @my_new_array = [] before like dima did with a = [] but two questions:

Why is a local variable my_new_array not working but just @ instance or $ global variables and why do I have
initialize this varriable? I think you don't need this in ruby? But without initialisation it just shows nil?


It's about scope. I'm sure the veterans here can give you a thorough
explanation, (and please pipe in here, because I don't want to spread
disinformation), but basically the block tries to retain its own scope
as best it can (from what I understand). So, new variables that are
not "swallowed" from the scope outside of the block need to be
initialized, and those initialized within the block don't get outside
of the block (what happens in Vegas stays in Vegas, blah blah).

Simple example...

irb(main):001:0> a = 1,2,3,4
=> [1, 2, 3, 4]
irb(main):002:0> a.each { |i| b = i } #nothing happens here outside of
the block for b
=> [1, 2, 3, 4]
irb(main):003:0> b
NameError: undefined local variable or method `b' for main:eek:bject


Here's one that will make you think a little that is somewhat OT, but
demonstrates namespace danger...

irb(main):001:0> a = 1,2,3,4
=> [1, 2, 3, 4]
irb(main):002:0> a.inject{ |s, a| s + a }
=> 10
irb(main):003:0> a
=> 4

The a is not the accumulator, but it has changed even though the
method doesn't have a ! following it. These are the small
idiosyncrasies that we have to be aware of with namespace and scope.

I may not be understanding your question, though.

Todd
 
R

Robert Klemme

2007/8/29 said:
The beauty is that you can do the same stuff in so many different
ways ;-)

I'll offer up an inject solution for this one:

my_new_array = myvalue.inject([]) {|arr, h| arr + h.values}

That's already pretty good (you used #inject ;-)) but this one is
slightly more efficient:

my_new_array = myvalue.inject([]) {|arr, h| arr.concat h.values}

Kind regards

robert
 
T

Todd Benson

2007/8/29 said:
my_new_array = myvalue.inject([]) {|arr, h| arr + h.values}

That's already pretty good (you used #inject ;-)) but this one is
slightly more efficient:

my_new_array = myvalue.inject([]) {|arr, h| arr.concat h.values}

Nice. You beat me to it. One of these days, though, I'll read all
the Ruby source and exact vengeance upon you guys :)

For a short repeat of the record for the nubies, #concat supposedly
doesn't create new objects, and thus is more "efficient".

Todd
 
R

Robert Klemme

2007/8/29 said:
my_new_array = myvalue.inject([]) {|arr, h| arr + h.values}
That's already pretty good (you used #inject ;-)) but this one is
slightly more efficient:

my_new_array = myvalue.inject([]) {|arr, h| arr.concat h.values}

Nice. You beat me to it. One of these days, though, I'll read all
the Ruby source and exact vengeance upon you guys :)
*gulp*

For a short repeat of the record for the nubies, #concat supposedly
doesn't create new objects, and thus is more "efficient".

To be fair I'd have to say that often intuition errs about what is fast
and what is wrong in Ruby. Sometimes algorithms that are supposedly
faster (for example because a collection is iterated only once vs.
several times) are actually slower than other variants - at least for
the size of collections that programs typically deal with. (In this
case if's of course better to save all those superfluous intermediate
arrays. :))

Kind regards

robert
 
T

Todd Benson

2007/8/29, (e-mail address removed) <[email protected]>:
On Aug 29, 2:53 pm, dima <[email protected]> wrote:
my_new_array = myvalue.inject([]) {|arr, h| arr + h.values}
That's already pretty good (you used #inject ;-)) but this one is
slightly more efficient:

my_new_array = myvalue.inject([]) {|arr, h| arr.concat h.values}

Nice. You beat me to it. One of these days, though, I'll read all
the Ruby source and exact vengeance upon you guys :)

*gulp*

Hopefully, everybody took that in good stride :)
To be fair I'd have to say that often intuition errs about what is fast
and what is wrong in Ruby. Sometimes algorithms that are supposedly
faster (for example because a collection is iterated only once vs.
several times) are actually slower than other variants - at least for
the size of collections that programs typically deal with. (In this
case if's of course better to save all those superfluous intermediate
arrays. :))

Yes. I've noticed a good deal of discussion along these lines in this
group, and it fascinates me (thus the comment about the source code
:).

Also, there are good lessons about software engineering in general on
this list (a group comprised of very smart people that sometimes I
feel as if I do not really belong), like: being careful about
emphasizing efficiency in the design phase, and then grabbing the
program by the proverbial balls later on :)
Kind regards

robert

Learning a ton of things every day,

Thanks,

Todd
 
R

Robert Klemme

2007/8/29, (e-mail address removed) <[email protected]>:
my_new_array = myvalue.inject([]) {|arr, h| arr + h.values}
That's already pretty good (you used #inject ;-)) but this one is
slightly more efficient:

my_new_array = myvalue.inject([]) {|arr, h| arr.concat h.values}
Nice. You beat me to it. One of these days, though, I'll read all
the Ruby source and exact vengeance upon you guys :)
*gulp*

Hopefully, everybody took that in good stride :)

I can speak for myself only but I did.
Yes. I've noticed a good deal of discussion along these lines in this
group, and it fascinates me (thus the comment about the source code
:).

Also, there are good lessons about software engineering in general on
this list (a group comprised of very smart people that sometimes I
feel as if I do not really belong), like: being careful about
emphasizing efficiency in the design phase, and then grabbing the
program by the proverbial balls later on :)

:) If that feeling haunts you again simply remember that all smart
people started out as dumb as everyone else. Also, as long as one
actually feels stupid one won't forget that one does not know the answer
to everything - it helps me keeping things in perspective.

Much of this smartness is just a matter of experience, namely having run
into the same traps and made the same mistakes that others haven't hit
so far. :)

And: You are absolutely right: this is a great community and it's good
that someone states it from time to time.
Learning a ton of things every day,

Definitively!

Kind regards

robert
 
M

Matthias Wächter

Why is a local variable my_new_array not working but just @ instance or $ global variables and why do I have
initialize this varriable? I think you don't need this in ruby? But without initialisation it just shows nil?

It's about scope. I'm sure the veterans here can give you a thorough
explanation, (and please pipe in here, because I don't want to spread
disinformation), but basically the block tries to retain its own scope
as best it can (from what I understand). So, new variables that are
not "swallowed" from the scope outside of the block need to be
initialized, and those initialized within the block don't get outside
of the block (what happens in Vegas stays in Vegas, blah blah).

Simple example...

irb(main):001:0> a = 1,2,3,4
=> [1, 2, 3, 4]
irb(main):002:0> a.each { |i| b = i } #nothing happens here outside of
the block for b
=> [1, 2, 3, 4]
irb(main):003:0> b
NameError: undefined local variable or method `b' for main:eek:bject


Here's one that will make you think a little that is somewhat OT, but
demonstrates namespace danger...

irb(main):001:0> a = 1,2,3,4
=> [1, 2, 3, 4]
irb(main):002:0> a.inject{ |s, a| s + a }
=> 10
irb(main):003:0> a
=> 4

The a is not the accumulator, but it has changed even though the
method doesn't have a ! following it. These are the small
idiosyncrasies that we have to be aware of with namespace and scope.

Is there something I can do to avoid name clashes for block parameters?

f.e. standard:

x="external"
a= 1,2,3,4

a.each {|x| puts x*x}
puts x # => 4

vs. clash avoision (note the exclamation mark):

x="external"
a= 1,2,3,4

a.each {|!x| puts x*x}
puts x # => "external"



- Matthias
 

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

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top