我有一个格式为
的文本文件date=1638.1.16
player=\"BYZ\"
savegame_version={
\tfirst=1
\tsecond=25
\tthird=1
\tforth=0
\tname=\"England\"
}
mod_enabled={
\t\"Large Font\"
\t\"Large Tooltips\"
}
我想要做的是将其作为字符向量列表读入R,其中{和}符号表示另一个列表的创建。结果应如下所示:
[[1]]
[1] "date=1638.1.16"
[[2]]
[1] "player=\"BYZ\""
[[3]]
[[3]][[1]]
[1] "savegame_version={"
[[3]][[2]]
[1] "\tfirst=1"
[[3]][[3]]
[1] "\tsecond=25"
[[3]][[4]]
[1] "\tthird=1"
[[3]][[5]]
[1] "\tforth=0"
[[3]][[6]]
[1] "\tname=\"England\""
[[3]][[7]]
[1] "}"
[[4]]
[[4]][[1]]
[1] "mod_enabled={"
[[4]][[2]]
[1] "\t\"Large Font\""
[[4]][[3]]
[1] "\t\"Large Tooltips\""
[[4]][[4]]
[1] "}"
我尝试使用创建列表的函数迭代数据行,其中{符号递归地再次调用相同的函数。问题是结果只是一个列表,而不是如上所示的嵌套列表。
当前函数写为:
list_create <- function(vector){
temp_list <- list()
for(i in 1:length(vector)){
if(str_detect(vector[i], pattern = "\\{")) {
list_create(vector[i+1:length(vector)])
}
if(str_detect(vector[i], pattern = "\\}")) {
return(temp_list)
}
temp_list <- append(temp_list, vector[i])
}
}
有没有办法得到我想要的结果?
答案 0 :(得分:0)
您有多少层子列表?对于您提供的示例(只有2个级别的列表),这应该有效:
# read the file in
txt <- readLines("listtext.txt")
# create an empty list
main.list <- list()
# indicator that we are within sublist
sub=FALSE
# loop through each line
for( i in seq(txt) ){
# check if the string opens a new sublist
if ( grepl("\\{", txt[i]) ){
sub.list <- list() # start a new sublist
sub.list <- c(sub.list, txt[i]) # add the line as the first line in the new list
sub = TRUE # inside the sublist
# check if we need to close sublist
} else if(grepl("\\}", txt[i]) ){
sub.list <- c(sub.list, txt[i]) # add the last line to sublist
main.list <- c(main.list, list(sub.list)) # add sublist to the main list
sub=FALSE # no longer inside sublist
# if we are within sublist
} else if(sub) {
sub.list <- c(sub.list, txt[i])
# regular record
} else {
main.list <- c(main.list, txt[i] )
}
}
main.list
# [[1]]
# [1] "date=1638.1.16"
#
# [[2]]
# [1] "player=\\\"BYZ\\\""
#
# [[3]]
# [[3]][[1]]
# [1] "savegame_version={"
#
# [[3]][[2]]
# [1] "\\tfirst=1"
#
# [[3]][[3]]
# [1] "\\tsecond=25"
#
# [[3]][[4]]
# [1] "\\tthird=1"
#
# [[3]][[5]]
# [1] "\\tforth=0"
#
# [[3]][[6]]
# [1] "\\tname=\\\"England\\\""
#
# [[3]][[7]]
# [1] "}"
#
#
# [[4]]
# [[4]][[1]]
# [1] "mod_enabled={"
#
# [[4]][[2]]
# [1] "\\t\\\"Large Font\\\""
#
# [[4]][[3]]
# [1] "\\t\\\"Large Tooltips\\\""
#
# [[4]][[4]]
# [1] "}"
如果你有许多递归子列表,那么你可以写一个递归函数:
main.list <- list()
subfun <- function(istart, txt){
sub.list <- list()
sub.list <- c(sub.list, txt[istart])
j = istart + 1
while( !grepl("\\}", txt[j]) ){
if ( grepl("\\{", txt[j]) ){
x <- subfun(j, txt)
sub.list <- c(sub.list, list(x$sub) ) # add sublist to the main list
j=x$iend
# regular record
} else {
sub.list <- c(sub.list, txt[j] )
}
j <- j+1
}
sub.list <- c(sub.list, txt[j])
return(list(sub=sub.list, iend=j))
}
# loop through each line
i=1
while( i <= length(txt) ){
# check if the string opens a new sublist
if ( grepl("\\{", txt[i]) ){
x <- subfun(i, txt)
main.list <- c(main.list, list(x$sub) ) # add sublist to the main list
i=x$iend
# regular record
} else {
main.list <- c(main.list, txt[i] )
}
i <- i+1
}
对于您的示例,它将产生与第一种方法相同的结果