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

Discussion in 'Ruby' started by kazaam, Aug 29, 2007.

  1. kazaam

    kazaam Guest

    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=>"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/"}]


    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.youtube.com/watch?v=JMDcOViViNY
    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.


    --
    kazaam <>
    kazaam, Aug 29, 2007
    #1
    1. Advertising

  2. kazaam

    Phrogz Guest

    Re: How to make an array of hashes to a single array with all the values of these hashes ?

    On Aug 29, 12:39 pm, kazaam <> wrote:
    > 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
    Phrogz, Aug 29, 2007
    #2
    1. Advertising

  3. kazaam

    dima Guest

    Re: How to make an array of hashes to a single array with all the values of these hashes ?

    On Aug 29, 8:45 pm, Phrogz <> wrote:
    > On Aug 29, 12:39 pm, kazaam <> wrote:
    >
    > > 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
    dima, Aug 29, 2007
    #3
  4. kazaam

    Guest

    Re: How to make an array of hashes to a single array with all the values of these hashes ?

    On Aug 29, 2:53 pm, dima <> wrote:

    > 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
    , Aug 29, 2007
    #4
  5. myvalue.to_s[3..-1].split('url')

    Regards
    Florian
    Florian Aßmann, Aug 29, 2007
    #5
  6. kazaam

    kazaam Guest

    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
    --
    kazaam <>
    kazaam, Aug 30, 2007
    #6
  7. kazaam

    Todd Benson Guest

    Re: How to make an array of hashes to a single array with all the values of these hashes ?

    On 8/30/07, kazaam <> wrote:
    > 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.

    > kazaam <>


    Todd
    Todd Benson, Aug 30, 2007
    #7
  8. Re: How to make an array of hashes to a single array with all the values of these hashes ?

    2007/8/29, <>:
    > On Aug 29, 2:53 pm, dima <> wrote:
    >
    > > 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
    Robert Klemme, Aug 30, 2007
    #8
  9. kazaam

    Todd Benson Guest

    Re: How to make an array of hashes to a single array with all the values of these hashes ?

    On 8/30/07, Robert Klemme <> wrote:
    > 2007/8/29, <>:
    > > On Aug 29, 2:53 pm, dima <> 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 :)

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

    Todd
    Todd Benson, Aug 30, 2007
    #9
  10. On 30.08.2007 16:47, Todd Benson wrote:
    > On 8/30/07, Robert Klemme <> wrote:
    >> 2007/8/29, <>:
    >>> On Aug 29, 2:53 pm, dima <> 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*

    > 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
    Robert Klemme, Aug 30, 2007
    #10
  11. kazaam

    Todd Benson Guest

    Re: How to make an array of hashes to a single array with all the values of these hashes ?

    On 8/30/07, Robert Klemme <> wrote:
    > On 30.08.2007 16:47, Todd Benson wrote:
    > > On 8/30/07, Robert Klemme <> wrote:
    > >> 2007/8/29, <>:
    > >>> On Aug 29, 2:53 pm, dima <> 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
    Todd Benson, Aug 31, 2007
    #11
  12. On 31.08.2007 02:09, Todd Benson wrote:
    > On 8/30/07, Robert Klemme <> wrote:
    >> On 30.08.2007 16:47, Todd Benson wrote:
    >>> On 8/30/07, Robert Klemme <> wrote:
    >>>> 2007/8/29, <>:
    >>>>> On Aug 29, 2:53 pm, dima <> 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 :)


    I can speak for myself only but I did.

    >> 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 :)


    :) 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
    Robert Klemme, Aug 31, 2007
    #12
  13. Scope Issues (avoid name clashes for block parameters)

    On 30.08.2007 16:22, Todd Benson wrote:
    > On 8/30/07, kazaam <> wrote:
    >> 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
    Matthias Wächter, Sep 13, 2007
    #13
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Trond
    Replies:
    0
    Views:
    283
    Trond
    Jul 17, 2004
  2. Eric Layman
    Replies:
    3
    Views:
    625
    Rad [Visual C# MVP]
    Apr 14, 2007
  3. Matt Brooks
    Replies:
    16
    Views:
    228
    Matt Brooks
    Sep 16, 2009
  4. Tim O'Donovan

    Hash of hashes, of hashes, of arrays of hashes

    Tim O'Donovan, Oct 27, 2005, in forum: Perl Misc
    Replies:
    5
    Views:
    212
  5. mrstevegross
    Replies:
    3
    Views:
    135
    Tad J McClellan
    Nov 11, 2008
Loading...

Share This Page