我是Clojure的新手,对于一般的函数式编程来说相当新。我试图创建一个生成字符串所有可能重新排列的anagram生成器。我以为我会对它进行概括,然后对列表进行所有可能的重新排列。
我的尝试:
(defn pairs [items]
(list (list (first items) (last items))
(list (last items) (first items))))
(defn prepend-to-list-or-item [item coll]
(if (coll? coll)
(map #(cons item %) coll)
(list item coll)))
(defn remove-one [coll item]
(let [[n m]
(split-with (partial not= item) coll)]
(concat n (rest m))))
(defn get-combinations [items]
(cond (= 0 (count items)) nil
(= 1 (count items)) items
(= 2 (count items)) (pairs items)
:else
(map #(prepend-to-list-or-item % (get-combinations (remove-one items %))) items)))
我遇到的问题是我得到的嵌套列表太深了。我得到的输出是:
clojure-test.combinations> (clojure.pprint/pprint (get-combinations '(\a \b \c)))
(((\a \b \c) (\a \c \b))
((\b \a \c) (\b \c \a))
((\c \a \b) (\c \b \a)))
nil
我想要的输出:
((\a \b \c) (\a \c \b) (\b \a \c) (\b \c \a) (\c \a \b) (\c \b \a))
随着更多列表项,问题会变得更糟。
所以,有两个问题:
答案 0 :(得分:2)
尝试
:else
(mapcat #(
为什么:
(map list-producing-function a-list) ; will give you a list of lists
ad 2。)
我将coll
改为chars
,将item
改为char
- 这仅供我理解
您可以简化删除一个
(如果我读得正确你确实想要没有项目的coll,这正是filter
的用途)
(defn remove-one [chars char]
(filter (partial not= char) chars))
获取组合,更具可读性的案例陈述
(let [char-count (count chars)]
(case char-count
0 nil
1 chars
2 (pairs chars)
(mapcat