这个功能如何运作?特别是,我在这里理解juxt
的功能时遇到了问题。
(fn [s]
(drop 1 (iterate (fn [s]
(mapcat (juxt count first)
(partition-by identity s))) s)))
答案 0 :(得分:3)
这似乎是康威look-and-say sequence的生成器。
这会产生类似
的序列(1) ; there is 1 "1" here, so...
(1 1) ; now there are 2 "1"s here, so...
(2 1) ; now there is 1 "2" and 1 "1"
(1 2 1 1) ; now there is 1 "1", 1 "2", and 2 "1"s, so...
(1 1 1 2 2 1) ; now there are 3 "1"s, 2 "2"s, and 1 "1", so ...
(3 1 2 2 1 1) ; etc.
drop 1
从序列序列输出中删除输入序列,但由于它也正确地属于看起来顺序的序列,我们可能会删除它。
我们所拥有的是(iterate look-say initial-seq)
其中
(defn look-say [s]
(mapcat
(juxt count first)
(partition-by identity s)))
所有迭代都是重复输入函数的输出作为输入,产生一系列中间结果。
要了解look-say功能,请从内到外进行操作。让我们从上面示例输出的倒数第二行开始作为一个很好的例子。
(def s '(1 1 1 2 2 1))
我们想要连续重复分组
(def grouped-s (partition-by identity s))
grouped-s ;=> ((1 1 1) (2 2) (1))
然后“说出”每组的计数
(map count grouped-s)
;=> (3 2 1)
但我们正在计算的是什么
(map first grouped-s)
;=> (1 2 1)
但我们宁愿同时获得计数和项目
(map (juxt count first) grouped-s)
;=> ([3 1] [2 2] [1 1])
几乎就在那里,只需要将所有这些连接在一起
(apply concat (map (juxt count first) grouped-s))
;=> (3 1 2 2 1 1)
与
相同(mapcat (juxt count first) grouped-s)
;=> (3 1 2 2 1 1)
请注意,您也可以将其写为
(for [g (partition-by identity s)
f [count first]]
(f g))
;=> (3 1 2 2 1 1)
可能更清楚或帮助解释前者。