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 <kazaam@oleco.net>

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: sepp2k@jabber.org
ICQ: 205544826

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

···

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

but how to achieve this? any idea or suggestion?

--
goto 10: http://www.goto10.it
blog it: http://riffraff.blogsome.com
blog en: http://www.riffraff.info

-------- Original-Nachricht --------

Datum: Sat, 29 Sep 2007 22:40:07 +0900
Von: kazaam <kazaam@oleco.net>
An: ruby-talk@ruby-lang.org
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 <kazaam@oleco.net>

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: GMX E-Mail ✉ sichere & kostenlose E-Mail-Adresse ✉

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 } ]

···

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

but how to achieve this? any idea or suggestion?

--
Julian 'Julik' Tarkhanov
please send all personal mail to
me at julik.nl

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/

···

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

--
we can deny everything, except that we have the possibility of being better. simply reflect on that.
h.h. the 14th dalai lama

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

···

--
kazaam <kazaam@oleco.net>

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

require 'ostruct'

O=> true

o=OpenStruct.new(:a=>1)

=> #<OpenStruct a=1>

o.a

=> 1

···

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

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

--
goto 10: http://www.goto10.it
blog it: http://riffraff.blogsome.com
blog en: http://www.riffraff.info