patternrubyMinor
Deserializer in ruby
Viewed 0 times
deserializerrubystackoverflow
Problem
Given a serialized hash of any depth in string format, convert it into a hash object.
I want to know if my approach is correct, I am capturing states and storing the results in a stack and generating the hash from the stack. Also, is there a name for this kind of parsing approach?
I want to know if my approach is correct, I am capturing states and storing the results in a stack and generating the hash from the stack. Also, is there a name for this kind of parsing approach?
def deserialize(input)
h = {}
l = 0
stack = []
curr_string = ""
while l 0 then
val = stack.pop
key = stack.pop
stack.push({key => val})
end
curr_string = ""
else
curr_string+=input[l]
end
l+=1
end
stack.each {|n| h.merge!(n)}
h
end
p deserialize("{a:test,b:test1,c:test3}")
p deserialize("{a:{b:test1}}")
p deserialize("{a:{b:{c:test1}}}")
p deserialize("{a:{b:{c:test1}},d:123}")Solution
The name for this type of parsing is called the shunting yard algorithm.
Your code itself seems fine, as long as you don't intend to support strings with curly braces, e.g.
Your code itself seems fine, as long as you don't intend to support strings with curly braces, e.g.
deserialize("{a:{b:'{{{{{{{{'}}"). The biggest issue I see is that it's not very ruby-like in the naming or formatting. I've made brief attempt at cleaning it up a little below.def deserialize(input)
hash = {} # avoid one letter variable names
stack = []
curr_string = '' # use single quotes for uninterpolated strings
input.chars.each do |c| # This is a better was to loop through the characters
case c
when '{'
curr_string = ''
# whitespace makes it easier to read the different cases
when ':'
stack.push(curr_string)
curr_string = ''
when '}', ','
stack.push(curr_string) unless curr_string.empty? # unless is the same as "if not"
# also use one line statements when the logic is simple
if stack.length > 0
val = stack.pop
key = stack.pop
stack.push({key => val})
end
curr_string = ''
else
curr_string += c
end
end
stack.each { |n| hash.merge!(n)}
hash
endCode Snippets
def deserialize(input)
hash = {} # avoid one letter variable names
stack = []
curr_string = '' # use single quotes for uninterpolated strings
input.chars.each do |c| # This is a better was to loop through the characters
case c
when '{'
curr_string = ''
# whitespace makes it easier to read the different cases
when ':'
stack.push(curr_string)
curr_string = ''
when '}', ','
stack.push(curr_string) unless curr_string.empty? # unless is the same as "if not"
# also use one line statements when the logic is simple
if stack.length > 0
val = stack.pop
key = stack.pop
stack.push({key => val})
end
curr_string = ''
else
curr_string += c
end
end
stack.each { |n| hash.merge!(n)}
hash
endContext
StackExchange Code Review Q#149731, answer score: 2
Revisions (0)
No revisions yet.