Flatten recursive list

前端 未结 4 1181
无人共我
无人共我 2021-02-14 09:33

There are quite a few questions apparently on this topic, but I can\'t see any general solution proposed: I have a deeply recursive list and want to flatten it into a single lis

4条回答
  •  野趣味
    野趣味 (楼主)
    2021-02-14 09:40

    Your data:

    d <- list(
      list(
        list(
          iris[sample(1:150,3),],
          iris[sample(1:150,3),]
        ),
        list(
          list(
            iris[sample(1:150,3),],
            list(
              iris[sample(1:150,3),],
              iris[sample(1:150,3),]
            )
          )
        )
      )
    )
    

    First, a crude, but effective function:

    f <- function(x) {
    
      if (is.null(x)) return
      n <- length(x)
    
      if (length(n) == 0) return
    
      for (i in 1:n) {
    
        if (is.data.frame(x[[i]])) {
          res <<- append(res, list(x[[i]]))
        } else {
          if (is.list(x[[i]])) {
            f(x[[i]])
          }
        }
    
      }
    
    }
    

    The crude but effective accompanying global variable:

    res <- list()
    
    f(d)
    

    The results:

    res
    ## [[1]]
    ##    Sepal.Length Sepal.Width Petal.Length Petal.Width Species
    ## 37          5.5         3.5          1.3         0.2  setosa
    ## 16          5.7         4.4          1.5         0.4  setosa
    ## 8           5.0         3.4          1.5         0.2  setosa
    ## 
    ## [[2]]
    ##     Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
    ## 10           4.9         3.1          1.5         0.1     setosa
    ## 141          6.7         3.1          5.6         2.4  virginica
    ## 86           6.0         3.4          4.5         1.6 versicolor
    ## 
    ## [[3]]
    ##     Sepal.Length Sepal.Width Petal.Length Petal.Width   Species
    ## 134          6.3         2.8          5.1         1.5 virginica
    ## 40           5.1         3.4          1.5         0.2    setosa
    ## 3            4.7         3.2          1.3         0.2    setosa
    ## 
    ## [[4]]
    ##     Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
    ## 33           5.2         4.1          1.5         0.1     setosa
    ## 132          7.9         3.8          6.4         2.0  virginica
    ## 76           6.6         3.0          4.4         1.4 versicolor
    ## 
    ## [[5]]
    ##     Sepal.Length Sepal.Width Petal.Length Petal.Width   Species
    ## 10           4.9         3.1          1.5         0.1    setosa
    ## 16           5.7         4.4          1.5         0.4    setosa
    ## 135          6.1         2.6          5.6         1.4 virginica
    

    Less crude (no global variable) solution:

    f2 <- function(x) {
    
      res <- list()
    
      if (is.null(x)) return
      n <- length(x)
    
      if (length(n) == 0) return
    
      for (i in 1:n) {
        if (is.data.frame(x[[i]])) {
          res <- append(res, list(x[[i]]))
        } else {
          if (is.list(x[[i]])) res <- append(res, f2(x[[i]]))
        }
      }
    
      return(res)
    
    }
    
    f2(d)
    ## same output
    

提交回复
热议问题