Dear all,
i am trying to find my way in Ruby, but i am just a bignner. Here is my
problem:
I have two array of hashes:
_DownloadData << { :FileName => splitLine[0] ,
:Size => splitLine[4].to_i }
_FilesData << { :FileName => splitLine[8] ,
:Year => year ,
:Month => month ,
:Day => day ,
:Suffix => suffix ,
:JDay => jday ,
:Size => splitLine[4].to_i }
I would like to know if FileName from _FileesData is in _DownloadData
and later or if the two files have the same size.
I tried to write it like this:
if _DownloadData[:FileName].include?( _FilesData[:FileName] )
and i already got an error.
what i would like to write is something like this:
_FilesData.sort_by {|hash| hash.values_at(:Year, :Month, :Day, :Suffix )
}.each do |hash|
if _DownloadData[:FileName].include?( hash[:FileName] )
index = _DownloadData[:FileName].index?( _FilesData[:FileName] )
if _DownloadData[:FileName](index) == _FilesData[:FileName]
# do something
else
# do something else
end
end
end
My questions are:
how do i fine an element of array of hashes in another array of hashes?
How do i get accuess an array of hashes at a certen index.
Thanks
on 19.08.2008 18:16
on 19.08.2008 18:30
On 19.08.2008 18:13, Adgar Marks wrote: > _FilesData << { :FileName => splitLine[8] , > :Year => year , > :Month => month , > :Day => day , > :Suffix => suffix , > :JDay => jday , > :Size => splitLine[4].to_i } I assume _DownloadData and _FilesData are of type Array. > I would like to know if FileName from _FileesData is in _DownloadData > and later or if the two files have the same size. > > I tried to write it like this: > if _DownloadData[:FileName].include?( _FilesData[:FileName] ) > > and i already got an error. Well, if they are arrays you rather need something like this: _DownloadData.each |dl| x = _FilesData.find {|fl| fl[:FileName] == dl[:FileName]} if x # found end end But note that this is inefficient if you have multiple entries in both arrays. In that case building a hash with the file name as key could speed up things considerably. Btw, conventionally variables in Ruby have all lowercase names with underscores and no leading underscore. Kind regards robert
on 19.08.2008 18:50
Thanks for the fast answer, Robert Klemme wrote: > On 19.08.2008 18:13, Adgar Marks wrote: >> _FilesData << { :FileName => splitLine[8] , >> :Year => year , >> :Month => month , >> :Day => day , >> :Suffix => suffix , >> :JDay => jday , >> :Size => splitLine[4].to_i } > > I assume _DownloadData and _FilesData are of type Array. > >> I would like to know if FileName from _FileesData is in _DownloadData >> and later or if the two files have the same size. >> >> I tried to write it like this: >> if _DownloadData[:FileName].include?( _FilesData[:FileName] ) >> >> and i already got an error. > > Well, if they are arrays you rather need something like this: > > _DownloadData.each |dl| > x = _FilesData.find {|fl| fl[:FileName] == dl[:FileName]} > if x > # found > end > end this x, is simply "true" or "fales", it is not exactly the solution i am searching for. I would like to find a file name from one array of hashes in the array hashes and then to compair the file size of both identical filenames... > > But note that this is inefficient if you have multiple entries in both > arrays. In that case building a hash with the file name as key could > speed up things considerably. > > Btw, conventionally variables in Ruby have all lowercase names with > underscores and no leading underscore. > > Kind regards > > robert Thanks
on 19.08.2008 19:35
On 19.08.2008 18:47, Adgar Marks wrote: >>> :Size => splitLine[4].to_i } >> > filenames... This shows that you did not try it out or read the docs. Sorry to say that. robert
on 19.08.2008 20:00
Dear Robert, I read your answer and also tried it! If it would have been a simple Array, then i wouldnt have need to ask it in the forum, because it is trivial. Example from http://www.ruby-doc.org/core/ a = [ "a", "b", "c" ] a.include?("b") #=> true a.include?("z") #=> false I read your remark: "But note that this is inefficient if you have multiple entries in both arrays." whic is exaclty my case, which i tried to explain my writing: _FilesData << { :FileName => splitLine[8] , :Year => year , :Month => month , :Day => day , :Suffix => suffix , :JDay => jday , :Size => splitLine[4].to_i } i thought i explained my problem clearly, that my arrays are multidimentions, by writing that they dont have the same size and explain the structre of each Array of hashes. I am not a Ruby expert and neither an expert programer, that is why i am asking for help. Thnaks
on 19.08.2008 21:38
I'm not Robert, but at least we both live in the same country, so I'll answer anyway: 2008/8/19 Adgar Marks <adgar.marks@yahoo.de>: > Dear Robert, > > I read your answer and also tried it! If you really tried it, then you haven't looked at the result of the method #find. Just try each step in IRB and look at the results. > If it would have been a simple Array, then i wouldnt have need to ask it > in the forum, because it is trivial. > > Example from http://www.ruby-doc.org/core/ > a = [ "a", "b", "c" ] > a.include?("b") #=> true > a.include?("z") #=> false You do have simple arrays, too, but the elements are not strings but hashes, so you can't compare them as easily as strings. If you would define classes for your objects with appropriate comparison methods, then your code could look as simple as the one you've shown. > I read your remark: > "But note that this is inefficient if you have multiple entries in both > arrays." > whic is exaclty my case, which i tried to explain my writing: > ... > i thought i explained my problem clearly, that my arrays are > multidimentions, by writing that they dont have the same size and > explain the structre of each Array of hashes. I'm sure Robert understands your problem exactly, but it seems you don't understand his answer, in which he mentioned a more efficient data structure: hashes of hashes. > I am not a Ruby expert and neither an expert programer, that is why i am > asking for help. From what I can tell of Robert's posts he is both a Ruby (at least an #inject :-) expert and an expert programmer, and he already gave you the answer to your question (again: just try it) plus a hint how you should change your data structures. Regards, Pit
on 20.08.2008 07:40
On 19.08.2008 21:32, Pit Capitain wrote: > I'm not Robert, but at least we both live in the same country, so I'll > answer anyway: Hm, Adgar has a yahoo.de address and you claim "we both live in the same country" - in that case I'd say all of us three live in the same country. :-)) > 2008/8/19 Adgar Marks <adgar.marks@yahoo.de>: >> I read your answer and also tried it! > > If you really tried it, then you haven't looked at the result of the > method #find. Just try each step in IRB and look at the results. >> I read your remark: >> "But note that this is inefficient if you have multiple entries in both >> arrays." >> whic is exaclty my case, which i tried to explain my writing: >> ... Good, then you probably want the nested Hash solution. Or rather create a data structure for your data and put it into a Hash indexed by file name, e.g. FileData = Struct.new :file_name, :year, :month, :day, :suffix, :j_day, :size dat = FileData.new splitLine[8], ... I do not know what you do with that but storing the data as a Date is probably better for consistency reasons. >> i thought i explained my problem clearly, that my arrays are >> multidimentions, by writing that they dont have the same size and >> explain the structre of each Array of hashes. Actually I'd say those Arrays are not multidimensional. Each Array covers one dimension only but they contain complex structures (as opposed to simple String or Fixnum). > I'm sure Robert understands your problem exactly, but it seems you > don't understand his answer, in which he mentioned a more efficient > data structure: hashes of hashes. This was probably my fault: I was a bit too brief. I should at least have mentioned that the object in question is returned from #find. There was just the small "hint" that I saved it in a variable. And I also should have mentioned IRB... :-) Sorry for that, posting in a hurry does not always yield good results. Adgar, if you feel more comfortable with German there is also Usenet group de.comp.lang.ruby. Kind regards robert