我是Clojure的新手,我很难通过数据结构习惯性地实现基本操作。
在Clojure中实现以下代码的惯用方法是什么?
AppBarLayout#setExpanded
答案 0 :(得分:5)
最简单的(但不是最多的FP-ish)几乎与你的例子相同:
(let [v [1 2 3 4 5 6 7]]
(mapcat #(map (partial vector (first %)) (rest %))
(take-while not-empty (iterate rest v))))
这里有更多功能变体来生成所有这些对(它不是基于长度或索引,而是基于尾部迭代):
([1 2] [1 3] [1 4] [1 5] [1 6] [1 7] [2 3] [2 4]
[2 5] [2 6] [2 7] [3 4] [3 5] [3 6] [3 7] [4 5]
[4 6] [4 7] [5 6] [5 7] [6 7])
输出:
doseq
然后只需在(let [v [1 2 3 4 5 6 7]
pairs (fn [items-seq]
(mapcat #(map (partial vector (first %)) (rest %))
(take-while not-empty (iterate rest items-seq))))]
(doseq [[i1 i2] (pairs v)] (println i1 i2)))
中使用这些对就可以产生任何副作用:
doseq
更新:关注@ dg123的回答。这很好,但你可以使用for
和(let [v [1 2 3 4 5 6 7]]
(doseq [[x & xs] (iterate rest v)
:while xs
y xs]
(println "x:" x "y:" y)))
的功能,如解构和守卫,让它变得更好:
iterate
你遍历集合的尾部,但请记住,user> (take 10 (iterate rest [1 2 3 4 5 6 7]))
([1 2 3 4 5 6 7] (2 3 4 5 6 7) (3 4 5 6 7)
(4 5 6 7) (5 6 7) (6 7) (7) () () ())
会产生无限的焦点:
[x & xs]
所以你必须以某种方式限制它只包括非空集合。
解构形式user> (let [[x & xs] [1 2 3 4 5 6]]
(println x xs))
1 (2 3 4 5 6)
nil
将参数拆分为第一个参数和其余参数的序列:
xs
当绑定的集合为空或具有单个元素时,nil
将为user> (let [[x & xs] [1]]
(println x xs))
1 nil
nil
:
:while
所以你只需使用此功能,在列表理解中使用x
后卫。
最后你只为xs
和Process
答案 1 :(得分:3)
如何使用map vector
和iterate
:
user=> (def l [1 2 3 4 5])
#'user/l
user=> (map vector l (iterate rest (drop 1 l)))
([1 (2 3 4 5)] [2 (3 4 5)] [3 (4 5)] [4 (5)] [5 ()])
生成每个i
索引的值的延迟序列,后跟其所有j
个。
然后您可以使用for
迭代所需的所有值对,如下所示:
user=> (for [[i js] (map vector l (iterate rest (drop 1 l)))
j js]
[i j])
([1 2] [1 3] [1 4] [1 5] [2 3] [2 4] [2 5] [3 4] [3 5] [4 5])
如果您想执行IO而不是生成延迟序列,请使用doseq
:
user=> (doseq [[i js] (map vector l (iterate rest (drop 1 l)))
j js]
(println (str "i: " i " j: " j)))
i: 1 j: 2
i: 1 j: 3
i: 1 j: 4
i: 1 j: 5
i: 2 j: 3
i: 2 j: 4
i: 2 j: 5
i: 3 j: 4
i: 3 j: 5
i: 4 j: 5
nil