代码之家  ›  专栏  ›  技术社区  ›  Crocodopolis

将嵌套列表折叠到方括号中

  •  3
  • Crocodopolis  · 技术社区  · 7 年前

    我希望编写一个函数,将具有任意长度和级别数的嵌套列表转换为字符串,该字符串可以作为LaTeX包中树的输入 forest .

    下面是我走了多远。我设法将树中的每个无子节点都括在方括号中,但如何检索中间节点的名称并将它们连接到单个字符串中?

    中的字符串 森林 环境显示了我想将示例列表转换为的内容。

    \documentclass[a4paper]{article}
    \usepackage{forest}
    \begin{document}
    <<list>>=
    library("tidyverse")
    nestedlist <- list("A"=list("B"=45:50, "C"=LETTERS[21:26],
        "D"=list("E"=7:10, "F"=list("G","H"))))                   
    squarebrackets <- function(x){
        if(class(x) == "list")
            map(x, squarebrackets)
        else
            paste0("[",x,"]") %>%
                paste0(., collapse="")
    }
    
    squarebrackets(nestedlist)
    @
    \begin{forest}
    [A[B[45][46][47][48][49][50]][C[U][V][W][X][Y][Z]][D[E[7][8][9][10]][F[G][H]]]]
    \end{forest}
    \end{document}
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   henrik_ibsen    7 年前

    一种方法是利用 unlist() . 这也将 F=c("G", "H") F=list("G", "H") 以同样的方式对待。

    以下示例不允许在节点名称中使用数字,并且节点名称必须是唯一的。这可能可以通过使用 rapply() 取而代之的是接近。

    定义备选方案 squarebrackets

    squarebracketsAlt <- function(inlist){
    
      #create the name hierarchy
      storeList <- unlist(inlist)
    
      #get unique names which represents levels in hierarchy
      uniqueNames <- unique(unlist(strsplit(gsub("[0-9]", "", names(storeList)), "\\.")))
    
      #keep the names to search for length of node brackets
      vecNames <- names(storeList)
      storeVec <- paste0("[", storeList, "]")
      names(storeVec) <- vecNames
    
      for(i in  uniqueNames){
    
        #determine the two positions of the node brackets
        whereBrack <- grep(paste0("\\.",i, "\\."),
                           paste0(".", gsub("[0-9]", "", names(storeVec)), "."))
    
        #add the start bracket and node name to vector
        storeVec <- append(storeVec, paste0("[", i), after=(whereBrack[1]-1))
        #add the end bracket to vector
        storeVec <- append(storeVec, paste0("]") , after=(whereBrack[length(whereBrack)]+1))
    
    
      }
      #collapse and output
      cat(paste(storeVec, collapse=""))
    
    }
    

    在嵌套列表中尝试:

    nestedlist <- list("A"=list("B"=45:50, "C"=LETTERS[21:26],
                                "D"=list("E"=7:10, "F"=list("G","H")))) 
    
    squarebracketsAlt(nestedlist)
    

    输出:

    [A[B[45][46][47][48][49][50]][C[U][V][W][X][Y][Z]][D[E[7][8][9][10]][F[G][H]]]]
    

    enter image description here

    较大层次结构示例:

    nestedlist1 <- list("Ad fe"=list("B"=45:50, "C"=list("U"=letters[1:10],LETTERS[22:26]),
                                    "D"=list("E"=7:10, "F"=list("G"=list("ZZ foo"=list("AA bar"=c(1:10),2,3,4,5)),"H", "C"))))  
    
    squarebracketsAlt(nestedlist1)
    

    输出:

    [Ad fe[B[45][46][47][48][49][50]][C[U[a][b][c][d][e][f][g][h][i][j]][V][W][X][Y][Z]][D[E[7][8][9][10]][F[G[ZZ foo[AA bar[1][2][3][4][5][6][7][8][9][10]][2][3][4][5]]][H][C]]]]
    

    enter image description here

    真实生活示例:

    nestedlist2 <- list("Main Area"=
                         list("Fishing vessel"=c("trawler", "line", "skipper"), "Oil tanker"=c("Large", "Small", "Medium size"=
                              list("Barents Sea", "Norwegian Sea", "Kara Sea", "Greenland"))))
    squarebracketsAlt(nestedlist2)
    

    输出:

    [Main Area[Fishing vessel[trawler][line][skipper]][Oil tanker[Large][Small][Medium size[Barents Sea][Norwegian Sea][Kara Sea][Greenland]]]]
    

    enter image description here


    前导数字示例:

    squarebracketsAltNum <- function(inlist){
    
      #create the name hierarchy
      storeList <- unlist(inlist)
    
      #get unique names which represents levels in hierarchy
      uniqueNames <- unique(paste(gsub("[A-z].*", "", unlist(strsplit(names(storeList), "\\."))),
                                  unlist(strsplit(gsub("[0-9]", "", names(storeList)), "\\.")), sep=""))
    
      #keep the names to search for length of node brackets
      vecNames <- names(storeList)
      storeVec <- paste0("[", storeList, "]")
      names(storeVec) <- vecNames
      k <- 1
    
      for(i in  uniqueNames){
        cat(i, "\n")
        #determine the two positions of the node brackets
        whereBrack <- grep(paste0("\\.",i),
                           paste0(".", names(storeVec)))
    
        #change position of number and character
        namePaster <- unique(paste(unlist(strsplit(gsub("[0-9]", "", names(storeList)), "\\.")),
                                   gsub("[A-z].*", "", unlist(strsplit(names(storeList), "\\."))), sep=""))[k]
    
    
        #add the start bracket and node name to vector
        storeVec <- append(storeVec, paste0("[", namePaster), after=(whereBrack[1]-1))
        #add the end bracket to vector
        storeVec <- append(storeVec, paste0("]") , after=(whereBrack[length(whereBrack)]+1))
        k <- k+1
    
      }
      #collapse and output
      cat(paste(storeVec, collapse=""))
    
    }
    

    数字和单词/句子之间没有空格。摆弄regexp以修复:

    nestedlist <- list("100A"=list("4B"=45:50, "3C"=LETTERS[21:26],
                                   "D"=list("E"=7:10, "78F"=c("G","H"))))          
    squarebracketsAlt(nestedlist)
    

    输出:

    [A100[B4[45][46][47][48][49][50]][C3[U][V][W][X][Y][Z]][D[E[7][8][9][10]][F78[G][H]]]]