From: Brian Candler Date: 2007-02-07T00:13:01+09:00 Subject: Re: Parse csv similar file On Tue, Feb 06, 2007 at 11:54:59PM +0900, Rebhan, Gilbert wrote: > > what kind of collection is the best ? is an array sufficient ? > /* > Depends what you want to do with it. If you want to be able to find an > entry > E123456 quickly, then you'd use a hash. If you want to keep only the > first/last entry for a particular key (as it seems you do), using a hash > speeds things up here too. > */ > > i don't need to find all entries E..... , but collect all datas > that belong to the different E..... > > i want a collection for every E... that occurs, with all the lines > (except the E... itself) that contain that E in it > > /* > Try: > > efas = Hash.new > ... > efas[$3] = [$1,$2,$4,$5,$6] unless efas.has_key?($3) > ... > puts efas.inspect > */ > > that gives me only one dataset in the hash, but there are more > entries that have E123456 in it. I was just following your original example, which only kept the first line for a particular E key. If you want to keep them all, then I'd use a hash with each element being an array. efas[$3] ||= [] # create empty array if necessary efas[$3] << [$1,$2,$4,$5,$6] # add a new line So, given the following input aaa,bbb,E123,ddd,eee,fff ggg,hhh,E123,iii,jjj,kkk you should get efas = { "E123" => [ ["aaa","bbb","ddd","eee","fff"], ["ggg","hhh","iii","jjj","kkk"], ], } puts efas["E123"].size # 2 puts efas["E123"][0][3] # "eee" puts efas["E123"][1][3] # "jjj" In practice, to make it easier to manipulate this data, you'd probably want to create a class to represent each object, rather than using a 5-element array. You would give each attribute a sensible name. I don't know what these values mean, so I've just called them a to e here. class Myclass attr_accessor :a, :b, :c, :d, :e def initialize(a, b, c, d, e) @a = a @b = b @c = c @d = d @e = e end end ... efas[$3] ||= [] efas[$3] << Myclass.new($1,$2,$4,$5,$6) HTH, Brian.