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

K

kazaam

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
 
S

Sebastian Hungerecker

kazaam said:
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
 
G

gabriele renzi

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
 
A

Axel Etzold

-------- Original-Nachricht --------
Datum: Sat, 29 Sep 2007 22:40:07 +0900
Von: kazaam <[email protected]>
An: (e-mail address removed)
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

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
 
J

Julian Tarkhanov

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

ara.t.howard

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/
 

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top