自从我开始使用Clojure以来,我已经多次阅读过这类文章。
例如,在这里:How to convert map to a sequence?
在一些推文中,我并不记得确实或多或少地说过#34;如果你正在使用扁平化你可能会做错了#34;。
我想知道,flatten有什么问题?
答案 0 :(得分:5)
我认为这就是他们在你联系的答案中所谈论的内容:
so> ((comp flatten seq) {:a [1 2] :b [3 4]})
(:b 3 4 :a 1 2)
so> (apply concat {:a [1 2] :b [3 4]})
(:b [3 4] :a [1 2])
Flatten将从键和值中删除结构,这可能不是您想要的。在某些用例中,您确实希望删除嵌套序列的结构,并且为此类情况编写了flatten。但是对于地图的解构,你通常希望保持内部序列不变。
答案 1 :(得分:4)
任何flatten
都无法展平,它应该完整无损。在顶层,它没有。
(flatten 8)
()
(flatten {1 2, 3 4})
()
如果您认为自己已经提供了一个序列,但是您没有,那么您将获得提供空序列的效果。这是大多数核心职能部门要排除的断路器。例如,(str nil) => ""
。
flatten
应该像这样工作:
(defn flatten [x]
(if (sequential? x)
((fn flat [y] (if (sequential? y) (mapcat flat y) [y])) x)
x))
(flatten 8)
;8
(flatten [{1 2, 3 4}])
;({1 2, 3 4})
(flatten [1 [2 [[3]] 4]])
;(1 2 3 4)
你可以找到Steve Miner这个here更快的懒惰版本。
答案 2 :(得分:2)
倾听那些说'#34;你可能做错了什么&#34;但也不要忘记他们说&#34;可能&#34;,因为这一切都取决于问题。< / p>
例如,如果你的任务是将地图展平,你可以在那里关心什么是关键值是什么,你只需要一个非结构化的序列,然后通过各种方式,使用展平(或apply concat
)。
它引起怀疑的原因&#34;事实上,你有map
开始,因此无论谁给你意味着一个&#34;关键价值&#34;配对结构,如果你展平它,你会失去意图,以及灵活性和清晰度。
如果您仍然不确定 与map
针对您的特定问题做什么,请记住for
理解,因为您将拥有完全控制权在迭代它时如何处理地图:
;; can also be (apply vector {:a 34 :b 42}), but just to use "for" for all consistently
user=> (into [] (for [[k v] {:a 34 :b 42}] [k v]))
[[:a 34] [:b 42]]
user=> (into {} (for [[k v] {:a 34 :b 42}] [k (inc v)]))
{:a 35, :b 43}
user=> (into #{} (for [[k v] {:a 34 :b 42}] [k v]))
#{[:a 34] [:b 42]}
user=> (into {} (for [[k v] {:a 34 :b 42}] [v k]))
{34 :a, 42 :b}