Clojure:测试运行属性的序列 [英] Clojure: Test a sequence for a running property
问题描述
假设您要针对只根据连续元素定义的属性测试Clojure序列。例如,单调性。
(defn monotonic?
[sequence]
; =(first%)(second%))
(partition 2 1 sequence)))
但我实际上想要做一些不同的属性。我可以复制每个,或我可以抽象:
(defn sequence-has-property?
[f sequ)
(每个?#(应用f%)
(分区2 1序列)))
b $ b
如果我想抽象出测试依赖的先前术语的数量(例如,#(=%3(+%%2))可以测试广义斐波那契模式)我可以写:
(defn sequence-has-property?
[f sequ n]
问题:有更好的(更快/更惯用的)方式吗?
取自OP的连结问题:
接受可变参数,并使其执行分区/重复。你的单调吗?例如已经存在于核心中,并被称为 <=
(< = 1 2 4 5)
=> true
(< = 1 2 1 5)
=> false
这里是1,2和可变参数版本的来源:
(source< =)
(defn <=
)如果num以单调非递减顺序返回非nil ,
否则为false。
{:inline(fn [xy]`。clojure.lang.Numbers(lte〜x〜y)))
:inline-arities#{2}
:added1.0}
([x] true)
([xy](。clojure.lang.Numbers(lte xy)))
([xy&更多]
(if(< = xy)
(if(next more)
(recur y(first more)第一更多)))
false)))
工作方式相同,使用可变参数,并重复三次:
(defn fib?
[ab& ; [c& r]]
(if(= c(+ ab))
(if r
(recur bcr)
true)
false)
(fib?0 1 1)
=> true
(fib?2 3 5 8 13)
=> true
Suppose you want to test a Clojure sequence for a property that is defined only in terms of contiguous elements. For example, monotonicity.
(defn monotonic?
[sequence]
(every? #(<= (first %) (second %))
(partition 2 1 sequence)))
But I actually want to do this for a number of different properties. I could copy this for each, or I could abstract:
(defn sequence-has-property?
[f sequ]
(every? #(apply f %)
(partition 2 1 sequ)))
If I want to abstract out the number of previous terms on which a test is dependent (for example, so that #(= %3 (+ % %2)) could test for a generalized Fibonacci pattern), I could write:
(defn sequence-has-property? [f sequ n] (every? #(apply f %) (partition n 1 sequ)))
Question: Is there a better (faster/more idiomatic) way?
Taken from linked question of OP:
Just make the predicate function itself take variadic arguments, and have it do the partitioning / recurring. Your monotonic? for instance already exists in core, and is called <=
(<= 1 2 4 5)
=> true
(<= 1 2 1 5)
=> false
Here's the source for the 1, 2 and variadic arg versions:
(source <=)
(defn <=
"Returns non-nil if nums are in monotonically non-decreasing order,
otherwise false."
{:inline (fn [x y] `(. clojure.lang.Numbers (lte ~x ~y)))
:inline-arities #{2}
:added "1.0"}
([x] true)
([x y] (. clojure.lang.Numbers (lte x y)))
([x y & more]
(if (<= x y)
(if (next more)
(recur y (first more) (next more))
(<= y (first more)))
false)))
You can make a fib? work the same way, have it take variadic arguments and recur over triples:
(defn fib?
[a b & [c & r]]
(if (= c (+ a b))
(if r
(recur b c r)
true)
false))
(fib? 0 1 1)
=> true
(fib? 2 3 5 8 13)
=> true
这篇关于Clojure:测试运行属性的序列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!