Clojure方式创建表示较大列表的边的子列表



给定条件:

["a" "bunch" "of" "words"]

我想要一个能产生的函数

[["a" "bunch"] ["a" "of"] ["a" "words"]
 ["bunch" "of"] ["bunch" "words"]
 ["of" "words"]]

我基本上是想列举第一个向量中单词的边缘。

类似这样的事情已经接近了:

(for [i lst, j (rest lst) :when (not= i j)] (conj [] i j))

但它当然会倒退。换言之,当它们在第一次通过时就已经被捕获时,我最终得到了["words"bunk"]["words"of"]等

也许这需要通过循环重复手动完成?但首先我想检查一下我是否遗漏了一些明显的东西,或者一个已经存在的漂亮的核心函数。

试试这个:

(def lst ["a" "bunch" "of" "words"])
(let [cnt (count lst) r (range cnt)]
  (for [a r b r :when (< a b)]
    [(lst a) (lst b)]))

;=> (["a" "bunch"] ["a" "of"] ["a" "words"] ["bunch" "of"] ["bunch" "words"] ["of" "words"])

这似乎与打印4x4矩阵的上三角形相同。

如果你希望结果是矢量,那么

(apply vector 
       (let [cnt (count lst) r (range cnt)]
         (for [a r b r :when (< a b)]
           [(lst a) (lst b)])))

一种简单的递归方式:

(defn edges [[f & r]]
  (when f (concat (map #(do [f %]) r) (edges r))))

最新更新