Hello guys.
I’ve just started using ruby and I come from Python… I’m still
learning to think the Ruby way…
Of course, any beginning is hard, but even so I’ve been having a lot
of fun learning Ruby.
The problem is that I still don’t know much about the tons of methods
and I’m maybe letting something pass through my fingers.
My problem is this:
I have to read a file and set up a data structure of embedded
dictionaries. In Python I can easily do that by means of
“dict.defaultdict()”, but I didn’t understand how to do that in
Ruby… I finally came up with the following:
def preprocess(lines)
d = {}
lines.each do |line|
c, s, fc, fl = line.split("\t")
if !d.has_key? c
d[c] = {}
end
if !d[c].has_key? s
d[c][s] = {}
end
if !d[c][s].has_key? fc
d[c][s][fc] = []
end
d[c][s][fc].push fl
end
return d
end
My question is: Is there an easier way to do this in Ruby as it is in
Python?
Same code in Python…
def preprocess(lines):
d = {}
for line in lines:
c, s, fc, fl = line
dc = d.setdefault(c, {})
ds = dc.setdefault(s, {})
dfc = ds.setdefault(fc, [])
lfl = dfc.append(fl)
return d
Thank you very much!
2009/8/28 David A. Black [email protected]:
learning to think the Ruby way…
dictionaries. In Python I can easily do that by means of
if !d[c].has_key? s
My question is: Is there an easier way to do this in Ruby as it is in
d[c][s] ||= {}
There are also ways to set the default behavior of hashes, but I think
the above is probably the most direct way to do what you want.
You mean something like the more involved
def preprocess(lines)
d = Hash.new {|h,k| h[k] = Hash.new(&h.default_proc)}
lines.each do |line|
c, s, fc, fl = line.split(“\t”)
(d[c][s][fc] ||= []) << fl
end
d
end
Kind regards
robert
Hi –
On Fri, 28 Aug 2009, Juliano 준호 wrote:
Hello guys.
I’ve just started using ruby and I come from Python… I’m still
learning to think the Ruby way…
Of course, any beginning is hard, but even so I’ve been having a lot
of fun learning Ruby.
Welcome! I’m glad you’re enjoying it.
d = {}
end
d[c][s][fc].push fl
end
return d
end
My question is: Is there an easier way to do this in Ruby as it is in
Python?
The idiom for conditional assignment in Ruby is ||= (or-equals). You
could do this:
def preprocess(lines)
d = {}
lines.each do |line|
c, s, fc, fl = line.split(“\t”)
d[c] ||= {}
d[c][s] ||= {}
d[c][s][fc] ||= []
d[c][s][fc].push fl
end
return d
end
The only thing is, in cases where you want false or nil to be a hash
value, ||= will over-eagerly do the assignment. But that’s not the
case here.
There are also ways to set the default behavior of hashes, but I think
the above is probably the most direct way to do what you want.
David
–
David A. Black / Ruby Power and Light, LLC / http://www.rubypal.com
September Ruby training in NJ has been POSTPONED. Stay tuned
for updates!
Hi –
On Fri, 28 Aug 2009, Robert K. wrote:
I’ve just started using ruby and I come from Python… I’m still
I have to read a file and set up a data structure of embedded
end
d[c] ||= {}
(d[c][s][fc] ||= []) << fl
end
d
end
Yes, that’s what I meant.
David
At 2009-08-28 06:16AM, “Juliano ??” wrote:
I have to read a file and set up a data structure of embedded
dictionaries. In Python I can easily do that by means of
“dict.defaultdict()”, but I didn’t understand how to do that in
Ruby… I finally came up with the following:
Referencing a hash element that doesn’t exist returns nil, so you might
be looking for the ||= operator:
a ||= b # if a is false or nil, then set a=b, else return value of
a
if !d[c][s].has_key? fc
d[c][s][fc] = []
end
d[c][s][fc].push fl
end
return d
end
def preprocess(lines)
d = {}
lines.each do |line|
c,s,fc,fl = line.split("\t")
d[c] ||= {}
d[c][s] ||= {}
d[c][s][fc] ||= []
d[c][s][fc] << fl
end
d
end