如何有效地自定义展平地图
How to efficiently custom flatten a map
因此,根据传递的 resourcesToCreate 参数,我必须相应地创建它们以创建流程
但现在的问题是,在分配 funcInput 时,json 实际上是根据它创建的流嵌套的,属性可以出现在任何地方,所以我无法进行 harcode。
Example
"config": {
"type": "func1",
"config": {
"param1": "10",
"param2": "10"
},
"connected": [
{
"type": "func3",
"config": {
"param1": "10",
"param2": "10"
},
"connected": [
{}
},
],
}
原来是这么想的 我把它弄平了 这样不管流量我都可以参考
{
"func1": {
"param1": "10",
"param2": "10"
},
"func3" : {
"param1": "10",
"param2": "10"
},
}
因此代码目前使 json 变胖,但无法获得所需的输出
func Flatten(prefix string, src map[string]interface{}, dest map[string]interface{}) {
if len(prefix) > 0 {
prefix += "."
}
for k, v := range src {
switch child := v.(type) {
case map[string]interface{}:
Flatten2(prefix+k, child, dest)
case []interface{}:
for i := 0; i < len(child); i++ {
dest[prefix+k+"."+strconv.Itoa(i)] = child[i]
}
default:
dest[prefix+k] = v
}
}
}
``
这种扁平化更像是提取值。通用方法是不可能的,但要依赖 type
、properties
和 connected
等 JSON 键来有效地提取 func
和 param
值.你的展平功能应该是这样的:
func keyValuePairs(m interface{}) map[string]interface{} {
kvs := make(map[string]interface{})
if reflect.ValueOf(m).Kind() == reflect.Map {
mp, ok := m.(map[string]interface{})
if ok {
var key string
var value interface{}
for k, v := range mp {
switch k {
case "type":
key = v.(string)
case "properties":
value = v
case "connected":
if collection, ok := v.([]interface{}); ok {
for _, c := range collection {
for nk, nv := range keyValuePairs(c) {
kvs[nk] = nv
}
}
}
default:
for nk, nv := range keyValuePairs(v) {
kvs[nk] = nv
}
}
}
if key != "" {
kvs[key] = value
}
} else {
for k, v := range m.(map[string]interface{}) {
kvs[k] = v
}
}
}
return kvs
}
与示例输入相同的代码:Go Playground
为了更好地理解代码片段,请查看此 gist 我实际上将 JSON 展平到最后的 key-value 对。
因此,根据传递的 resourcesToCreate 参数,我必须相应地创建它们以创建流程
但现在的问题是,在分配 funcInput 时,json 实际上是根据它创建的流嵌套的,属性可以出现在任何地方,所以我无法进行 harcode。
Example
"config": {
"type": "func1",
"config": {
"param1": "10",
"param2": "10"
},
"connected": [
{
"type": "func3",
"config": {
"param1": "10",
"param2": "10"
},
"connected": [
{}
},
],
}
原来是这么想的 我把它弄平了 这样不管流量我都可以参考
{
"func1": {
"param1": "10",
"param2": "10"
},
"func3" : {
"param1": "10",
"param2": "10"
},
}
因此代码目前使 json 变胖,但无法获得所需的输出
func Flatten(prefix string, src map[string]interface{}, dest map[string]interface{}) {
if len(prefix) > 0 {
prefix += "."
}
for k, v := range src {
switch child := v.(type) {
case map[string]interface{}:
Flatten2(prefix+k, child, dest)
case []interface{}:
for i := 0; i < len(child); i++ {
dest[prefix+k+"."+strconv.Itoa(i)] = child[i]
}
default:
dest[prefix+k] = v
}
}
}
``
这种扁平化更像是提取值。通用方法是不可能的,但要依赖 type
、properties
和 connected
等 JSON 键来有效地提取 func
和 param
值.你的展平功能应该是这样的:
func keyValuePairs(m interface{}) map[string]interface{} {
kvs := make(map[string]interface{})
if reflect.ValueOf(m).Kind() == reflect.Map {
mp, ok := m.(map[string]interface{})
if ok {
var key string
var value interface{}
for k, v := range mp {
switch k {
case "type":
key = v.(string)
case "properties":
value = v
case "connected":
if collection, ok := v.([]interface{}); ok {
for _, c := range collection {
for nk, nv := range keyValuePairs(c) {
kvs[nk] = nv
}
}
}
default:
for nk, nv := range keyValuePairs(v) {
kvs[nk] = nv
}
}
}
if key != "" {
kvs[key] = value
}
} else {
for k, v := range m.(map[string]interface{}) {
kvs[k] = v
}
}
}
return kvs
}
与示例输入相同的代码:Go Playground
为了更好地理解代码片段,请查看此 gist 我实际上将 JSON 展平到最后的 key-value 对。