作为加入DB公司的面试过程的一部分,我被要求实现一个例程来展平JSON对象。接受输入,例如
{
"a": 1,
"b": true,
"c": {
"d": 3,
"e": "test"
}
}
它应该输出
{
"a": 1,
"b": true,
"c.d": 3,
"c.e": "test"
}
输入将不包含数组,并且将是有效的JSON对象。
我最终没有通过此测试,也没有得到关于为什么的任何有用反馈,所以我认为我将在此处发布实现并寻求反馈。
// parseEntry flattens a json map. This function assumes that a map will not
// have arrays but can have a number of nested maps.
func parseEntry(m map[string]interface{}, k string, v interface{}, prefix string) {
// Since this function uses recursion, let's set some sort of limit on
// the number of recursive calls we allow.
if strings.Count(prefix, ".") > MaxFlatDepth {
return
}
switch vv := v.(type) {
default:
delete(m, k)
var newKey string
if len(prefix) != 0 {
newKey = fmt.Sprintf("%v.%v", prefix, k)
} else {
newKey = k
}
m[newKey] = v
case map[string]interface{}:
delete(m, k)
newMap := vv
var newPrefix string
for localKey, localVal := range newMap {
if len(prefix) != 0 {
newPrefix = fmt.Sprintf("%s.%v", prefix, k)
} else {
newPrefix = fmt.Sprintf("%v", k)
}
parseEntry(m, localKey, localVal, newPrefix)
}
}
}
回想一下,我希望我添加了更多评论,并解释得更好一些。我希望在他们做出决定之前至少与团队打个招呼,谈论我的实施情况。但是此时水在桥下。你们怎么看?
问题陈述需要更多说明。例如,您将前缀与嵌套json的键与“。”串联在一起。作为分隔符。因此,您必须确保输入json不会包含带有“。”的键。否则您的功能将失败。
{
"a": 1,
"c.d": true,
"c": {
"d": 3,
"e": "test"
}}
对于以上输入,您的函数可能最终会根据键的随机迭代顺序失去嵌套的json或布尔值键。
并且最好将MaxFlatDepth作为错误处理,而不是突然停止展平。您应该为所有情况给出正确的结果或报告错误。而且我不知道为什么您首先需要这个限制。我认为没有人能找到堆栈深度的确切值,该值最终会溢出并为MaxFlatDepth设置此配置。
func parseEntry(m map[string]interface{}, k string, v interface{}, prefix string) error {
if strings.Count(prefix, ".") > MaxFlatDepth {
return errors.New("Max Depth reached")
}
.....
采访者会很想知道您对解决问题的思考过程。在开始编写解决方案编码之前,您必须考虑一些极端情况并澄清您的疑问。您必须大声一点,让他们知道您找到解决方案的方法。向您解释您对他们做出的每一个决定。