2D array to array of hashes with repeating header

Discussion in 'Ruby' started by Jason Lillywhite, Sep 27, 2009.

  1. I have this array:
    data = [[:time, :pressure],[0,2.3],[1,4.1],[2,7.56],...]

    All the arrays in data could have an arbitrary number of items in it and
    the total number of arrays in data is arbitrary but all arrays will be
    the same size and the first array will always be the "header" array.

    I need to convert data to an array that looks like this:

    new_data =
    [{:time=>0,:pressure=>2.3},{:time=>1,:pressure=>4.1},{:time=>2,:pressure=>7.56}]

    Is there a straight forward way to set this up? I'm happy with hints.
    Thank you!
    --
    Posted via http://www.ruby-forum.com/.
     
    Jason Lillywhite, Sep 27, 2009
    #1
    1. Advertising

  2. Jason Lillywhite

    Josh Cheek Guest

    [Note: parts of this message were removed to make it a legal post.]

    On Sun, Sep 27, 2009 at 1:10 AM, Jason Lillywhite <
    > wrote:

    > I have this array:
    > data = [[:time, :pressure],[0,2.3],[1,4.1],[2,7.56],...]
    >
    > All the arrays in data could have an arbitrary number of items in it and
    > the total number of arrays in data is arbitrary but all arrays will be
    > the same size and the first array will always be the "header" array.
    >
    > I need to convert data to an array that looks like this:
    >
    > new_data =
    >
    > [{:time=>0,:pressure=>2.3},{:time=>1,:pressure=>4.1},{:time=>2,:pressure=>7.56}]
    >
    > Is there a straight forward way to set this up? I'm happy with hints.
    > Thank you!
    > --
    > Posted via http://www.ruby-forum.com/.
    >
    >

    This is destructive. If you want to keep the original data too, you can
    implement the same process slightly differently, but this was just cleaner.

    to_convert = [[:time, :pressure],[0,2.3],[1,4.1],[2,7.56]]

    header = to_convert.shift

    to_convert.map! do |ary|
    hsh = Hash.new
    ary.each_with_index{|val,index| hsh[header[index]] = val }
    hsh
    end

    to_convert # => [{:pressure=>2.3, :time=>0}, {:pressure=>4.1, :time=>1},
    {:pressure=>7.56, :time=>2}]
     
    Josh Cheek, Sep 27, 2009
    #2
    1. Advertising

  3. # I test this in ruby 1.9.1
    result = data[1..-1].map{|e| Hash[data[0].zip(e)]}

    # And this should work for all version
    result = data[1..-1].map{|e| data[0].zip(e).inject({}){|x,y|
    x[y[0]]=y[1]; x}}
    --
    Posted via http://www.ruby-forum.com/.
     
    Thairuby ->a, b {a + b}, Sep 27, 2009
    #3
  4. Jason Lillywhite

    timr Guest

    data = [[:time, :pressure],[0,2.3],[1,4.1],[2,7.56],...]
    axes = data.shift #shift the axes labels out from the data set
    new_data = data.collect{|point| {axes[0] => point[0], axes[1] => point
    [1]}} #pair the axes with the data by iterating and collecting the
    results

    Tim


    On Sep 26, 11:10 pm, Jason Lillywhite <>
    wrote:
    > I have this array:
    > data = [[:time, :pressure],[0,2.3],[1,4.1],[2,7.56],...]
    >
    > All the arrays in data could have an arbitrary number of items in it and
    > the total number of arrays in data is arbitrary but all arrays will be
    > the same size and the first array will always be the "header" array.
    >
    > I need to convert data to an array that looks like this:
    >
    > new_data =
    > [{:time=>0,:pressure=>2.3},{:time=>1,:pressure=>4.1},{:time=>2,:pressure=>7 .56}]
    >
    > Is there a straight forward way to set this up? I'm happy with hints.
    > Thank you!
    > --
    > Posted viahttp://www.ruby-forum.com/.
     
    timr, Sep 27, 2009
    #4
  5. Josh Cheek wrote:
    > to_convert = [[:time, :pressure],[0,2.3],[1,4.1],[2,7.56]]
    >
    > header = to_convert.shift
    >
    > to_convert.map! do |ary|
    > hsh = Hash.new
    > ary.each_with_index{|val,index| hsh[header[index]] = val }
    > hsh
    > end
    >
    > to_convert # => [{:pressure=>2.3, :time=>0}, {:pressure=>4.1, :time=>1},
    > {:pressure=>7.56, :time=>2}]


    Thank you. I have a question about this. I tried this and accidentally
    initialized the variable 'hsh' outside the map! method and could not get
    the correct result. I'm curious why this is wrong:

    header = to_convert.shift
    hsh = Hash.new
    to_convert.map! do |ary|
    ary.each_with_index{|val,index| hsh[header[index]] = val }
    hsh
    end

    to_convert # => [{:pressure=>7.56, :time=>2}, {:pressure=>7.56,
    :time=>2}, {:pressure=>7.56, :time=>2}]

    Thank you.
    --
    Posted via http://www.ruby-forum.com/.
     
    Jason Lillywhite, Oct 1, 2009
    #5
  6. On Thu, Oct 1, 2009 at 9:00 PM, Jason Lillywhite
    <> wrote:
    > Josh Cheek wrote:
    >> to_convert =3D [[:time, :pressure],[0,2.3],[1,4.1],[2,7.56]]
    >>
    >> header =3D to_convert.shift
    >>
    >> to_convert.map! do |ary|
    >> =A0 hsh =3D Hash.new
    >> =A0 ary.each_with_index{|val,index| hsh[header[index]] =3D val }
    >> =A0 hsh
    >> end
    >>
    >> to_convert # =3D> [{:pressure=3D>2.3, :time=3D>0}, {:pressure=3D>4.1, :t=

    ime=3D>1},
    >> {:pressure=3D>7.56, :time=3D>2}]

    >
    > Thank you. I have a question about this. I tried this and accidentally
    > initialized the variable 'hsh' outside the map! method and could not get
    > the correct result. I'm curious why this is wrong:
    >
    > header =3D to_convert.shift
    > hsh =3D Hash.new
    > to_convert.map! do |ary|
    > =A0ary.each_with_index{|val,index| hsh[header[index]] =3D val }
    > =A0hsh
    > end
    >
    > to_convert # =3D> [{:pressure=3D>7.56, :time=3D>2}, {:pressure=3D>7.56,
    > :time=3D>2}, {:pressure=3D>7.56, :time=3D>2}]


    Because in this case you are using the same object (referenced by hsh)
    for all iterations (map!). Map collects :))) all results from the
    blocks and puts them into an array. In your case, all iterations are
    returning the same object (hsh), and so your resulting array contains
    exactly the same values in all positions: in fact they are the *same*
    object. You can check this with object_id. In the proposed solution a
    new Hash object is created for each iteration, and so each position in
    the resulting array is a different object.

    Jesus.
     
    Jesús Gabriel y Galán, Oct 1, 2009
    #6
    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. Ben Holness

    Hashes of Hashes via subs

    Ben Holness, Oct 5, 2003, in forum: Perl
    Replies:
    8
    Views:
    572
    Ben Holness
    Oct 8, 2003
  2. Steven Arnold

    using hashes as keys in hashes

    Steven Arnold, Nov 23, 2005, in forum: Ruby
    Replies:
    3
    Views:
    168
    Mauricio Fernández
    Nov 23, 2005
  3. kazaam
    Replies:
    12
    Views:
    279
    Matthias Wächter
    Sep 13, 2007
  4. Matt Brooks
    Replies:
    16
    Views:
    231
    Matt Brooks
    Sep 16, 2009
  5. 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:
    217
Loading...

Share This Page