Clojure:测试运行属性的序列 [英] Clojure: Test a sequence for a running property

查看:135
本文介绍了Clojure:测试运行属性的序列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设您要针对只根据连续元素定义的属性测试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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆