[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

MultiValuedHash

chris

8/17/2007 8:54:00 AM

I have a lot of files in an folder and want loop over the files in a
special way:

Dir.entries("f:/test/").each { |e| filenames.push(e[3..50])}

Now i have an array with the distinct names like:
a.txt
b.txt
c.txt
d.txt
....
z.txt

, but every file "have 20 parts" which i have to proceed:
00_a.txt
01_a.txt
02_a.txt
...
19_a.txt


for i in 0..19
filenames.map{ |t| if i < 10 then p "0#{i}_#{t}" else p
"#{i}_#{t}" end }
end


I find something about MultiValuedHash, but i didn't know how i get my
structure (....the distinct names are the keys and the 20 parts for
every key as values ) like the raw_data in an easy way.

raw_data=[[1,'a'],[1,'b'],[1,'c'],[2,'a'],[2,['b','c']],
[3,'c']]

class MultiValuedHash < Hash
def []=(key,value)
if has_key?(key)
super(key,[value,self[key]].flatten)
else
super
end
end
end

hash=MultiValuedHash.new
raw_data.each{ |x,y| hash[x]=y }

many thanks & regards
Christian

3 Answers

Robert Klemme

8/17/2007 9:06:00 AM

0

2007/8/17, Christian <ozric@web.de>:
> I have a lot of files in an folder and want loop over the files in a
> special way:
>
> Dir.entries("f:/test/").each { |e| filenames.push(e[3..50])}
>
> Now i have an array with the distinct names like:
> a.txt
> b.txt
> c.txt
> d.txt
> ...
> z.txt
>
> , but every file "have 20 parts" which i have to proceed:
> 00_a.txt
> 01_a.txt
> 02_a.txt
> ..
> 19_a.txt
>
>
> for i in 0..19
> filenames.map{ |t| if i < 10 then p "0#{i}_#{t}" else p
> "#{i}_#{t}" end }
> end
>
>
> I find something about MultiValuedHash, but i didn't know how i get my
> structure (....the distinct names are the keys and the 20 parts for
> every key as values ) like the raw_data in an easy way.
>
> raw_data=[[1,'a'],[1,'b'],[1,'c'],[2,'a'],[2,['b','c']],
> [3,'c']]
>
> class MultiValuedHash < Hash
> def []=(key,value)
> if has_key?(key)
> super(key,[value,self[key]].flatten)
> else
> super
> end
> end
> end
>
> hash=MultiValuedHash.new
> raw_data.each{ |x,y| hash[x]=y }

This is shorter and more efficient:

hash = Hash.new {|h,k| h[k] = []}
raw_data.each{ |x,y| hash[x] << y }

And you even do not need a new class. :-)

Kind regards

robert

chris

8/17/2007 2:25:00 PM

0

On 17 Aug., 11:05, "Robert Klemme" <shortcut...@googlemail.com> wrote:
> 2007/8/17, Christian <oz...@web.de>:
>
>
>
> > I have a lot of files in an folder and want loop over the files in a
> > special way:
>
> > Dir.entries("f:/test/").each { |e| filenames.push(e[3..50])}
>
> > Now i have an array with the distinct names like:
> > a.txt
> > b.txt
> > c.txt
> > d.txt
> > ...
> > z.txt
>
> > , but every file "have 20 parts" which i have to proceed:
> > 00_a.txt
> > 01_a.txt
> > 02_a.txt
> > ..
> > 19_a.txt
>
> > for i in 0..19
> > filenames.map{ |t| if i < 10 then p "0#{i}_#{t}" else p
> > "#{i}_#{t}" end }
> > end
>
> > I find something about MultiValuedHash, but i didn't know how i get my
> > structure (....the distinct names are the keys and the 20 parts for
> > every key as values ) like the raw_data in an easy way.
>
> > raw_data=[[1,'a'],[1,'b'],[1,'c'],[2,'a'],[2,['b','c']],
> > [3,'c']]
>
> > class MultiValuedHash < Hash
> > def []=(key,value)
> > if has_key?(key)
> > super(key,[value,self[key]].flatten)
> > else
> > super
> > end
> > end
> > end
>
> > hash=MultiValuedHash.new
> > raw_data.each{ |x,y| hash[x]=y }
>
> This is shorter and more efficient:
>
> hash = Hash.new {|h,k| h[k] = []}
> raw_data.each{ |x,y| hash[x] << y }
>
> And you even do not need a new class. :-)
>
> Kind regards
>
> robert


many thanks for the trick

But have anybody an advice how i get the filenames a.txt, b.txt ....
as key and the parts 00_a.txt , 01_a.txt, 02_a.txt as values for
every key.

i identify a mistake to get the unique names i have to:
Dir.entries("f:/base_data/ADS20/outputdaten/").each { |e|
files.push(e[3..50])}
filenames.push(files.select{|e| files.index(e) !=
files.rindex(e)}.uniq)

many thanks & regards
Christian







Gordon Thiesfeld

8/17/2007 2:58:00 PM

0

> many thanks for the trick
>
> But have anybody an advice how i get the filenames a.txt, b.txt ....
> as key and the parts 00_a.txt , 01_a.txt, 02_a.txt as values for
> every key.
>
> i identify a mistake to get the unique names i have to:
> Dir.entries("f:/base_data/ADS20/outputdaten/").each { |e|
> files.push(e[3..50])}
> filenames.push(files.select{|e| files.index(e) !=
> files.rindex(e)}.uniq)
>

If you use the hash idiom Robert showed you, you won't have to worry
about checking for uniqueness, because all keys are unique. They'll
be created the first time you use them, and updated each time after
that. So, the filename is your key, and the file parts get added to
the array referenced by that key. I also used e[3..-1] instead of
e[3..50]. This will return the string from the 3rd character to the
end of the string, regardless of length.


hash = Hash.new {|h,k| h[k] = []}
Dir.entries(".").each do |e|
filename = e[3..-1]
hash[filename].push e
end