Is there a combination of a struct and an array? I wanna iterateover all created objects from a cert

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

  1. kazaam

    kazaam Guest

    I have a file with many entries and much of these I don't need. Let's imagine:

    name=arthur
    age=16
    hobby=swimming
    job=dancer
    home=DE
    name=marry
    age=49
    hobby=singing
    job=nurse
    home=US
    name=tom
    age=32
    hobby=crafting
    job=electician
    home=NW
    name=mantra
    age=22
    hobby=reading
    job=cop
    home=FR

    this is my file and I need just the name,hobby and home of each one.

    Now I read my file:

    File.open(myfile).each { |line|
    puts line.sub(/name=|hobby=|home=/,'') if line =~/name|hobby|home/
    }

    Which puts me the entries nicly on my screen. But I have to process them from my script. So I need some kind of an array struct which let's me iterate over each person and let's me use their name,hobby and home values. But how to achieve this? With with variable-typ and how to get the correctly collected?

    I wanna talk to them like this:

    person.each |entry| do
    puts entry.name
    puts entry.hobby
    puts entry.home
    end

    but how to achieve this? any idea or suggestion?

    bye
    --
    kazaam <>
     
    kazaam, Sep 29, 2007
    #1
    1. Advertising

  2. Re: Is there a combination of a struct and an array? I wanna iterate over all created objects from a certain struct-class (I guess).

    kazaam wrote:
    > I have a file with many entries and much of these I don't need. Let's
    > imagine:
    >
    > name=arthur
    > age=16
    > hobby=swimming
    > job=dancer
    > home=DE
    > name=marry
    > age=49
    > hobby=singing
    > job=nurse
    > home=US
    > [...]
    >
    > this is my file and I need just the name,hobby and home of each one.


    If the order is guaranteed, it's as simple as
    str.scan(/name=(.+?)\n.*?hobby=(.+?)\n.*?home=(\w+?)/m)


    > So I need some kind of an array struct which let's me
    > iterate over each person and let's me use their name,hobby and home values.
    > But how to achieve this? With with variable-typ and how to get the
    > correctly collected?


    You don't need "some kind of array struct" (whatever that would be) - just an
    array (which may of course contain structs).

    > I wanna talk to them like this:
    >
    > person.each |entry| do
    > puts entry.name
    > puts entry.hobby
    > puts entry.home
    > end


    Person=Struct.new:)name, :hobby, :home)
    re=/name=(.+?)\n.*?hobby=(.+?)\n.*?home=(\w+)/m
    persons=File.read(file).scan(re).map { |arr| Person.new(*arr) }
    persons.each do |pers|
    puts pers.name
    puts pers.hobby
    puts pers.home
    end

    A more general solution that reads in all information about a person (even if
    you don't need it):
    persons=File.read(file).scan(/name=.*?(?=name=|\Z)/m).map do |pers|
    Hash[*pers.scan(/^(.*)=(.*)$/).flatten]
    end
    persons.each do
    puts pers["name"]
    puts pers["hobby"]
    puts pers["home"]
    end

    This solution doesn't require the order to be fixed, except that name= has to
    be the first entry for any person.


    Another solution that doesn't require any ordering in the file at all:
    str=File.read(file)
    Person=Struct.new:)name, :hobby, :home)
    names=str.scan(/name=(.*)$/).flatten
    hobbies=str.scan(/hobby=(.*)$/).flatten
    homes=str.scan(/home=(.*)$/).flatten
    persons=names.zip(hobbies,homes).map { |pers| Person.new(*pers) }
    persons.each do |pers|
    puts pers.name
    puts pers.hobby
    puts pers.home
    end


    HTH,
    Sebastian
    --
    NP: Mysticum - Mourning
    Jabber:
    ICQ: 205544826
     
    Sebastian Hungerecker, Sep 29, 2007
    #2
    1. Advertising

  3. Re: Is there a combination of a struct and an array? I wannaiterate over all created objects from a certain struct-class (I guess).

    On Sat, 29 Sep 2007 15:37:07 +0200, kazaam wrote:


    > but how to achieve this? any idea or suggestion?


    maybe:
    Person=Struct.new:)name,:hobby,:home)
    def read_data(io)
    io.gets.chomp.split('=')[1]
    end
    def read_person(io)
    name= read_data(io)
    hobby= read_data(io)
    job=io.gets
    home= read_data(io)
    Person.new(name,hobby,home)
    end
    people=[]
    people << read_person(DATA) while not DATA.eof?
    puts people

    or

    people={}
    name = nil
    DATA.each do |line|
    case line
    when /name=(.*)/
    name=$1
    people[name]= {'name'=>name}
    when /(hobby|home)=(.*)/
    people[name][$1]=$2
    end
    end
    p people

    HTH



    --
    goto 10: http://www.goto10.it
    blog it: http://riffraff.blogsome.com
    blog en: http://www.riffraff.info
     
    gabriele renzi, Sep 29, 2007
    #3
  4. kazaam

    Axel Etzold Guest

    -------- Original-Nachricht --------
    > Datum: Sat, 29 Sep 2007 22:40:07 +0900
    > Von: kazaam <>
    > An:
    > Betreff: Is there a combination of a struct and an array? I wanna iterate over all created objects from a certain struct-class (I guess).


    > I have a file with many entries and much of these I don't need. Let's
    > imagine:
    >
    > name=arthur
    > age=16
    > hobby=swimming
    > job=dancer
    > home=DE
    > name=marry
    > age=49
    > hobby=singing
    > job=nurse
    > home=US
    > name=tom
    > age=32
    > hobby=crafting
    > job=electician
    > home=NW
    > name=mantra
    > age=22
    > hobby=reading
    > job=cop
    > home=FR
    >
    > this is my file and I need just the name,hobby and home of each one.
    >
    > Now I read my file:
    >
    > File.open(myfile).each { |line|
    > puts line.sub(/name=|hobby=|home=/,'') if line =~/name|hobby|home/
    > }
    >
    > Which puts me the entries nicly on my screen. But I have to process them
    > from my script. So I need some kind of an array struct which let's me
    > iterate over each person and let's me use their name,hobby and home values. But
    > how to achieve this? With with variable-typ and how to get the correctly
    > collected?
    >
    > I wanna talk to them like this:
    >
    > person.each |entry| do
    > puts entry.name
    > puts entry.hobby
    > puts entry.home
    > end
    >
    > but how to achieve this? any idea or suggestion?
    >
    > bye
    > --
    > kazaam <>


    Dear Kazaam,

    you could create a class Person to do the job, something like

    class Person
    def initialize(name,hobby,age,job,home)
    @name=name
    @hobby=hobby
    @age=age
    @job=job
    @home=home
    end
    def name
    @name
    end
    def hobby
    @hobby
    end
    def age
    @age
    end
    def home
    @home
    end
    def job
    @job
    end
    end

    me=Person.new("Albert Einstein","physics",134,"retired","wonttellyou")
    p me.hobby

    There is a nice introduction to classes in Ruby in http://pine.fm/LearnToProgram, particularly in chapter 9.

    Best regards,

    Axel
    --
    GMX FreeMail: 1 GB Postfach, 5 E-Mail-Adressen, 10 Free SMS.
    Alle Infos und kostenlose Anmeldung: http://www.gmx.net/de/go/freemail
     
    Axel Etzold, Sep 29, 2007
    #4
  5. kazaam

    kazaam Guest

    Re: Is there a combination of a struct and an array? I wannaiterate over all created objects from a certain struct-class (I guess).

    thanks for you're answers I'll work through the different approaches now!

    --
    kazaam <>
     
    kazaam, Sep 29, 2007
    #5
  6. Re: Is there a combination of a struct and an array? I wanna iterate over all created objects from a certain struct-class (I guess).

    On 29-sep-2007, at 15:40, kazaam wrote:

    > but how to achieve this? any idea or suggestion?


    1) You parse the thing into a hash
    2) You use a sprinkle of _why's Ruby magick to structify a hash

    class H < Hash
    def method_missing(m,*a)
    m.to_s=~/=$/?self[$`]=a[0]:a==[]?self[m]:super
    end
    end

    H[{:foo=>"bar"}].foo #=> "bar"

    When mixed with your task, remember that you can pass a zipped array
    to Hash[] (zipped means [key, val, key, val, ...]), using the splat (*).
    So for your person entry the example becomes:

    entry = text_of_a_single_person_entry
    H[ *entry.split("\n").map{|line| line.split(/\=/) }.flatten.map{|
    key_or_val | key_or_val.strip } ]

    --
    Julian 'Julik' Tarkhanov
    please send all personal mail to
    me at julik.nl
     
    Julian Tarkhanov, Sep 29, 2007
    #6
  7. kazaam

    ara.t.howard Guest

    Re: Is there a combination of a struct and an array? I wanna iterate over all created objects from a certain struct-class (I guess).

    On Sep 29, 2007, at 7:40 AM, kazaam wrote:

    > I have a file with many entries and much of these I don't need.
    > Let's imagine:
    >
    > name=arthur
    > age=16
    > hobby=swimming
    > job=dancer
    > home=DE
    > name=marry
    > age=49
    > hobby=singing
    > job=nurse
    > home=US
    > name=tom
    > age=32
    > hobby=crafting
    > job=electician
    > home=NW
    > name=mantra
    > age=22
    > hobby=reading
    > job=cop
    > home=FR


    they arrayfields gem is going to make this *very* easy and clear:



    cfp:~ > cat a.rb
    require 'enumerator'
    require 'arrayfields' ### gem install arrayfields

    re = %r/\s* ([^=]+) \s* = \s* ([^=]+) \s* \n/iomx
    kvs = DATA.read.scan re

    records = [] and kvs.each_slice(5){|record| records << Arrayfields
    [record]}

    records.each{|record| record.each_pair{|key, value| puts "#{ key } : #
    { value }"}}

    __END__
    name=arthur
    age=16
    hobby=swimming
    job=dancer
    home=DE
    name=marry
    age=49
    hobby=singing
    job=nurse
    home=US
    name=tom
    age=32
    hobby=crafting
    job=electician
    home=NW
    name=mantra
    age=22
    hobby=reading
    job=cop
    home=FR



    cfp:~ > ruby a.rb
    name : arthur
    age : 16
    hobby : swimming
    job : dancer
    home : DE
    name : marry
    age : 49
    hobby : singing
    job : nurse
    home : US
    name : tom
    age : 32
    hobby : crafting
    job : electician
    home : NW
    name : mantra
    age : 22
    hobby : reading
    job : cop
    home : FR


    a @ http://drawohara.com/
    --
    we can deny everything, except that we have the possibility of being
    better. simply reflect on that.
    h.h. the 14th dalai lama
     
    ara.t.howard, Sep 29, 2007
    #7
  8. Re: Is there a combination of a struct and an array? I wannaiterate over all created objects from a certain struct-class (I guess).

    On Sun, 30 Sep 2007 00:48:54 +0900, Julian Tarkhanov wrote:

    > On 29-sep-2007, at 15:40, kazaam wrote:
    >
    >> but how to achieve this? any idea or suggestion?

    >
    > 1) You parse the thing into a hash
    > 2) You use a sprinkle of _why's Ruby magick to structify a hash


    2b) you use openstruct which does it for you :)
    >> require 'ostruct'

    O=> true
    >> o=OpenStruct.new:)a=>1)

    => #<OpenStruct a=1>
    >> o.a

    => 1
    >>




    --
    goto 10: http://www.goto10.it
    blog it: http://riffraff.blogsome.com
    blog en: http://www.riffraff.info
     
    gabriele renzi, Sep 30, 2007
    #8
    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. Holmes!
    Replies:
    2
    Views:
    448
    Malcolm Dew-Jones
    Apr 2, 2005
  2. Chris Fogelklou
    Replies:
    36
    Views:
    1,405
    Chris Fogelklou
    Apr 20, 2004
  3. Chris Rebert
    Replies:
    5
    Views:
    339
    Raymond Hettinger
    Apr 24, 2010
  4. David Chan via .NET 247
    Replies:
    1
    Views:
    355
    Dominick Baier [DevelopMentor]
    Jun 2, 2005
  5. Tuan  Bui
    Replies:
    14
    Views:
    495
    it_says_BALLS_on_your forehead
    Jul 29, 2005
Loading...

Share This Page