[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Find element in array of hashes

Adgar Marks

8/19/2008 4:13:00 PM

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
--
Posted via http://www.ruby-....

6 Answers

Robert Klemme

8/19/2008 4:26:00 PM

0

On 19.08.2008 18:13, Adgar Marks wrote:
> 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 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

Adgar Marks

8/19/2008 4:48:00 PM

0

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
--
Posted via http://www.ruby-....

Robert Klemme

8/19/2008 5:33:00 PM

0

On 19.08.2008 18:47, Adgar Marks wrote:
> 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...

This shows that you did not try it out or read the docs. Sorry to say that.

robert

Adgar Marks

8/19/2008 5:57:00 PM

0

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...
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
--
Posted via http://www.ruby-....

Pit Capitain

8/19/2008 7:32:00 PM

0

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...
> 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

Robert Klemme

8/20/2008 5:40:00 AM

0

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