Clojure: Semi-Flattening a nested Sequence

后端 未结 5 724
走了就别回头了
走了就别回头了 2020-12-04 18:59

I have a list with embedded lists of vectors, which looks like:

(([1 2]) ([3 4] [5 6]) ([7 8]))

Which I know is not ideal to work with. I\'d lik

5条回答
  •  南方客
    南方客 (楼主)
    2020-12-04 19:38

    Also you may found useful this general 1 level flatten function I found on clojuremvc:

    (defn flatten-1 
      "Flattens only the first level of a given sequence, e.g. [[1 2][3]] becomes
       [1 2 3], but [[1 [2]] [3]] becomes [1 [2] 3]."
      [seq]
      (if (or (not (seqable? seq)) (nil? seq))
        seq ; if seq is nil or not a sequence, don't do anything
        (loop [acc [] [elt & others] seq]
          (if (nil? elt) acc
            (recur
              (if (seqable? elt)
                (apply conj acc elt) ; if elt is a sequence, add each element of elt
                (conj acc elt))      ; if elt is not a sequence, add elt itself 
           others)))))
    

    Example:

    (flatten-1 (([1 2]) ([3 4] [5 6]) ([7 8])))
    =>[[1 2] [3 4] [5 6] [7 8]]
    

    concat exampe surely do job for you, but this flatten-1 is also allowing non seq elements inside a collection:

    (flatten-1 '(1 2 ([3 4] [5 6]) ([7 8])))
    =>[1 2 [3 4] [5 6] [7 8]]
    ;whereas 
    (apply concat '(1 2 ([3 4] [5 6]) ([7 8])))
    => java.lang.IllegalArgumentException: 
       Don't know how to create ISeq from: java.lang.Integer
    

提交回复
热议问题