CLJS中实现扁平化集合合并:求替代flatten的预定义函数
解决混合元素与集合的扁平化合并问题
首先明确flatten的风险:它会递归展开所有层级的嵌套集合,若输入里存在深层嵌套的集合(比如["IT" ["MX" ["deep-nested"]]]),flatten会把所有嵌套都摊平,这可能和你的预期不符,属于过度展开,确实存在安全隐患。
针对你的需求(将单个元素和集合参数合并为扁平化的顶层集合),可以用以下更可控的方案:
自定义可控的扁平化合并函数
自己封装一个函数,仅展开作为参数传入的顶层集合,元素内部的嵌套会保留:
(defn conj-flat [coll & args] (vec (apply concat coll (map #(if (coll? %) % [%]) args))))
测试示例:
;; 你的原始场景 (conj-flat ["IT" "AB"] "MX" ["ad" "cd"]) ;; 返回 ["IT" "AB" "MX" "ad" "cd"] ;; 含内部嵌套的情况,内部嵌套会保留 (conj-flat ["a"] ["IT" ["MX"]] "b") ;; 返回 ["a" "IT" ["MX"] "b"]
用Transducer实现(可选)
如果偏好Transducer风格,也可以用into配合cat来实现:
(into ["IT" "AB"] (comp (map #(if (coll? %) % [%])) cat) ["MX" ["ad" "cd"]])
关于预定义函数:Clojure/Script标准库没有直接提供完全匹配你需求的预定义函数——conj的语义是直接添加元素(哪怕元素是集合),concat只接受集合参数(传入单个元素会报错),因此自定义函数是最直接的解决方案。
内容的提问来源于stack exchange,提问作者Navneet Singh
相关产品推荐
相关产品推荐

