通过组合相似的名称来加入和组织 JSON 对象结构
Joining and organizing JSON object structure by combining like names
我有一个独特的 JSON 对象列表(指定为 json_object),所有对象都具有类似的结构,看起来像这样
{
"WREF": {
"PSME": {
"sbt": {
"upr": 68.34,
"lwr": 3.02
}
}
},
"WREF": {
"TSHE": {
"mbt": {
"upr": 39.425,
"lwr": -6.855
}
}
},
"WREF": {
"PSME": {
"mbt": {
"upr": 119.82,
"lwr": 16.02
}
}
},
"ABBY": {
"PSME": {
"sbt": {
"upr": 84.42,
"lwr": 9.02
}
}
},
"ABBY": {
"TSHE": {
"sbt": {
"upr": 39.05,
"lwr": 2.01
}
}
},
"ABBY": {
"TSHE": {
"mbt": {
"upr": 69.35,
"lwr": 4.07
}
}
}
}
我正在尝试 reorganize/restructure 将它们整理成这样更有条理的东西:
{
"WREF": {
"PSME": {
"sbt": {
"upr": 68.34,
"lwr": 3.02
},
"mbt": {
"upr": 119.82,
"lwr": 16.02
}
},
"TSHE": {
"mbt": {
"upr": 39.425,
"lwr": -6.855
}
}
},
"ABBY": {
"PSME": {
"sbt": {
"upr": 84.42,
"lwr": 9.02
}
},
"TSHE": {
"sbt": {
"upr": 39.05,
"lwr": 2.01
},
"mbt": {
"upr": 69.35,
"lwr": 4.07
}
}
},
}
我目前正在使用这段代码来完成它,但是它似乎只是将 JSON 的最高级别放在一起,例如 WREF 和 ABBY,而不是合并 PSME 和 TSHE 或任何较低级别的内容在 JSON 结构中。
#loop through each object
lapply( X = seq( 2, length( json_object), 1), FUN = function( x){
#if its the second object
if( x == 2){
#check if the first objects name matches and join
if( names( json_object[[ 1]]) %in% names( json_object[[ x]])){
final_object <<- Map( c, json_object[[1]], json_object[[ x]])
} else{
final_object <<- c( json_object[[ 1]], json_object[[ x]])
}
} else{ #if not the second object
#check if there are any matching names
if( names( json_object[[ x]]) %in% names( final_object)){
#join matching names
final_object[ names( json_object[[ x]])] <<- Map( c, final_object[ names( json_object[[ x]])],
json_object[[ x]]
)
} else{ #if not, just join
final_object <<- c( final_object, json_object[[ x]])
}
}
})
本例中的最终对象是这样的:
{
"WREF": {
"PSME": {
"sbt": {
"upr": 68.34,
"lwr": 3.02
},
},
"PSME": {
"mbt": {
"upr": 119.82,
"lwr": 16.02
}
},
"TSHE": {
"mbt": {
"upr": 39.425,
"lwr": -6.855
}
}
},
"ABBY": {
"PSME": {
"sbt": {
"upr": 84.42,
"lwr": 9.02
}
},
"TSHE": {
"sbt": {
"upr": 39.05,
"lwr": 2.01
}
},
"TSHE": {
"mbt": {
"upr": 69.35,
"lwr": 4.07
}
}
}
}
有没有简单的方法来做到这一点?最终我想用更复杂的 JSON 结构来做到这一点。
试试这个,将 txt1
定义为您的第一个 text/code 块:
json1 <- jsonlite::parse_json(txt1)
out1 <- lapply(
split(json1, names(json1)),
function(z) {
y <- do.call(c, unname(z))
lapply(split(y, names(y)),
function(x) do.call(c, unname(x)))
})
jsonlite::toJSON(out1, pretty = TRUE, auto_unbox = TRUE)
产生
{
"ABBY": {
"PSME": {
"sbt": {
"upr": 84.42,
"lwr": 9.02
}
},
"TSHE": {
"sbt": {
"upr": 39.05,
"lwr": 2.01
},
"mbt": {
"upr": 69.35,
"lwr": 4.07
}
}
},
"WREF": {
"PSME": {
"sbt": {
"upr": 68.34,
"lwr": 3.02
},
"mbt": {
"upr": 119.82,
"lwr": 16.02
}
},
"TSHE": {
"mbt": {
"upr": 39.425,
"lwr": -6.855
}
}
}
}
目前这是硬编码的两层深度。如果你需要它是任意的,那么上面的递归改编适用于这个例子;请注意,我还没有测试过其他类型的列表结构。
func <- function(obj) {
if (!is.list(obj)) return(obj)
tmp1 <- lapply(split(obj, names(obj)),
function(z) do.call(c, unname(z)))
lapply(tmp1, func)
}
out2 <- func(json1)
jsonlite::toJSON(out2, pretty = TRUE, auto_unbox = TRUE)
呈现与上述类似的输出,但由于递归性质,它不能确保保留列表的顺序。
我有一个独特的 JSON 对象列表(指定为 json_object),所有对象都具有类似的结构,看起来像这样
{
"WREF": {
"PSME": {
"sbt": {
"upr": 68.34,
"lwr": 3.02
}
}
},
"WREF": {
"TSHE": {
"mbt": {
"upr": 39.425,
"lwr": -6.855
}
}
},
"WREF": {
"PSME": {
"mbt": {
"upr": 119.82,
"lwr": 16.02
}
}
},
"ABBY": {
"PSME": {
"sbt": {
"upr": 84.42,
"lwr": 9.02
}
}
},
"ABBY": {
"TSHE": {
"sbt": {
"upr": 39.05,
"lwr": 2.01
}
}
},
"ABBY": {
"TSHE": {
"mbt": {
"upr": 69.35,
"lwr": 4.07
}
}
}
}
我正在尝试 reorganize/restructure 将它们整理成这样更有条理的东西:
{
"WREF": {
"PSME": {
"sbt": {
"upr": 68.34,
"lwr": 3.02
},
"mbt": {
"upr": 119.82,
"lwr": 16.02
}
},
"TSHE": {
"mbt": {
"upr": 39.425,
"lwr": -6.855
}
}
},
"ABBY": {
"PSME": {
"sbt": {
"upr": 84.42,
"lwr": 9.02
}
},
"TSHE": {
"sbt": {
"upr": 39.05,
"lwr": 2.01
},
"mbt": {
"upr": 69.35,
"lwr": 4.07
}
}
},
}
我目前正在使用这段代码来完成它,但是它似乎只是将 JSON 的最高级别放在一起,例如 WREF 和 ABBY,而不是合并 PSME 和 TSHE 或任何较低级别的内容在 JSON 结构中。
#loop through each object
lapply( X = seq( 2, length( json_object), 1), FUN = function( x){
#if its the second object
if( x == 2){
#check if the first objects name matches and join
if( names( json_object[[ 1]]) %in% names( json_object[[ x]])){
final_object <<- Map( c, json_object[[1]], json_object[[ x]])
} else{
final_object <<- c( json_object[[ 1]], json_object[[ x]])
}
} else{ #if not the second object
#check if there are any matching names
if( names( json_object[[ x]]) %in% names( final_object)){
#join matching names
final_object[ names( json_object[[ x]])] <<- Map( c, final_object[ names( json_object[[ x]])],
json_object[[ x]]
)
} else{ #if not, just join
final_object <<- c( final_object, json_object[[ x]])
}
}
})
本例中的最终对象是这样的:
{
"WREF": {
"PSME": {
"sbt": {
"upr": 68.34,
"lwr": 3.02
},
},
"PSME": {
"mbt": {
"upr": 119.82,
"lwr": 16.02
}
},
"TSHE": {
"mbt": {
"upr": 39.425,
"lwr": -6.855
}
}
},
"ABBY": {
"PSME": {
"sbt": {
"upr": 84.42,
"lwr": 9.02
}
},
"TSHE": {
"sbt": {
"upr": 39.05,
"lwr": 2.01
}
},
"TSHE": {
"mbt": {
"upr": 69.35,
"lwr": 4.07
}
}
}
}
有没有简单的方法来做到这一点?最终我想用更复杂的 JSON 结构来做到这一点。
试试这个,将 txt1
定义为您的第一个 text/code 块:
json1 <- jsonlite::parse_json(txt1)
out1 <- lapply(
split(json1, names(json1)),
function(z) {
y <- do.call(c, unname(z))
lapply(split(y, names(y)),
function(x) do.call(c, unname(x)))
})
jsonlite::toJSON(out1, pretty = TRUE, auto_unbox = TRUE)
产生
{
"ABBY": {
"PSME": {
"sbt": {
"upr": 84.42,
"lwr": 9.02
}
},
"TSHE": {
"sbt": {
"upr": 39.05,
"lwr": 2.01
},
"mbt": {
"upr": 69.35,
"lwr": 4.07
}
}
},
"WREF": {
"PSME": {
"sbt": {
"upr": 68.34,
"lwr": 3.02
},
"mbt": {
"upr": 119.82,
"lwr": 16.02
}
},
"TSHE": {
"mbt": {
"upr": 39.425,
"lwr": -6.855
}
}
}
}
目前这是硬编码的两层深度。如果你需要它是任意的,那么上面的递归改编适用于这个例子;请注意,我还没有测试过其他类型的列表结构。
func <- function(obj) {
if (!is.list(obj)) return(obj)
tmp1 <- lapply(split(obj, names(obj)),
function(z) do.call(c, unname(z)))
lapply(tmp1, func)
}
out2 <- func(json1)
jsonlite::toJSON(out2, pretty = TRUE, auto_unbox = TRUE)
呈现与上述类似的输出,但由于递归性质,它不能确保保留列表的顺序。