我是clojure的新手我试图找出clojure中的向量是否具有连续元素:在python中使用numpy 很简单
(np.diff(np.sort(np.array(numbers))))
但我在尝试寻找类似的方法时迷失了方向:我的策略是
- 用自身减去向量
- 让它成为一个集合,看看它是否包含作为1的第一个元素,并且集合的长度是1
例如(def x `(5 7 3 6 4))
输出为(1 1 1 1(
我不知道该怎么做。
试试这样的东西:
(defn diff [vals]
(map - (next vals) vals))
这将返回每对连续元素之间的差异列表。它之所以有效,是因为next
只是将值序列偏移一个元素。
示例用法:
(diff [1 2 2 3])
=> (1 0 1)
要测试是否存在连续的数字,只需检查该列表中是否存在值1
。
根据您获得差异的想法,排序后,您可以使用partition来获得所有连续的对,然后使用map来获得所有差异。(在这里,获得numpy-diff的反向似乎更自然,因此检查每个元素都是-1
而不是1
。(
(defn contains-consecutive? [xs]
(let [sorted (sort xs)
differences (map #(apply - %) (partition 2 1 sorted))]
(every? #(= -1 %) differences)))
user> (contains-consecutive? [])
true
user> (contains-consecutive? [1])
true
user> (contains-consecutive? [1 3 2])
true
user> (contains-consecutive? [1 3 4])
false
user> (contains-consecutive? '(5 7 3 6 4))
true
Clojure有一个内置的重复数据消除功能,因此一个简单(但不是特别快(的答案是重复数据消除和比较相等值。
(defn consecutive?
[coll]
(not= coll (dedupe coll)))
(consecutive? [1 2 2 3]) ;; true
(consecutive? [1 2 3]) ;; false
请参阅此文档列表,尤其是Clojure CheatSheet。您正在查找函数partition
。你可以这样使用它:
(ns tst.demo.core
(:use tupelo.test))
(defn pair-delta
[pair]
(let [[a b] pair]
(- b a)))
(defn consectives?
[v]
(let [pairs (partition 2 1 (sort v))
deltas (mapv pair-delta pairs)
result (= #{1} (set deltas))]
result))
(dotest
(let [pos [1 2 3 6 5 4]
neg [1 2 3 6 5 ]]
(is= true (consectives? pos))
(is= false (consectives? neg))))
模板项目显示了我喜欢如何设置项目,并包括我最喜欢的助手函数。