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
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
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
Datum: Sat, 29 Sep 2007 22:40:07 +0900
Von: kazaam [email protected]
An: [email protected]
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).
hobby=singing
job=cop
Which puts me the entries nicly on my screen. But I have to process them
puts entry.home
end
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
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
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: