有没有一种快速的方法来检查一个序列在Clojure中是否只有1个元素?请注意,序列可能包含nils。
如果我正确读取source,则在序列上调用count
需要花费O(n)时间。
替代解决方案:
(and
(not (empty? a-seq))
(empty? (rest a-seq)))
Docs说在集合empty?
上调用coll
与调用(not (seq coll))
相同,但是他们没有指定效率或调用{{{}时发生的情况1}}关于一个序列。我试图在github存储库中搜索empty?
的实现方式,但它忽略了搜索中的问号,并且“空”上有大量点击。我认为empty?
和empty?
是O(1),但是再次,rest
不是......
答案 0 :(得分:3)
因为
reflect.TypeOf(myVar)
(函数终止的事实),我假设user=> (empty? (cycle [1]))
false
在恒定时间内进行求值,即empty?
在恒定时间内初始化序列。
(seq coll)
你的代码做得很好。也许我会说:
user=> (source empty?)
(defn empty?
"Returns true if coll has no items - same as (not (seq coll)).
Please use the idiom (seq x) rather than (not (empty? x))"
{:added "1.0"
:static true}
[coll] (not (seq coll)))
nil
答案 1 :(得分:3)
1.9中添加了以下功能(截至目前仍为alpha版):
(defn bounded-count
"If coll is counted? returns its count, else will count at most the first n
elements of coll using its seq"
{:added "1.9"}
[n coll]
(if (counted? coll)
(count coll)
(loop [i 0 s (seq coll)]
(if (and s (< i n))
(recur (inc i) (next s))
i))))
所以我想(bounded-count 2 coll)
应该为你提供所需的恒定时间。
答案 2 :(得分:3)
当序列变得懒惰时,你无法真正谈论“恒定时间”,因为在构造输入序列时可能会延迟任何工作量。例如,请考虑以下序列:
(filter even? (filter odd? (range)))
对此序列调用seq
将永远不会返回任何类型的结果,除非您等待的时间超过Long/MAX_VALUE
。
但是,通常,功能完全按照他们需要做的最少工作量来完成。所以seq
做了足够的工作来确定集合的第一个元素是什么,如果有的话,next
只做足够的工作来确定第一个和第二个元素是什么,如果有的话。
答案 3 :(得分:1)
几点说明:
文档说在集合上调用
empty?
与调用相同(not (seq coll))
,但他们没有指定效率或发生的事情 当你在一个序列上调用empty?
时。
empty?
适用于序列,无论是否基于集合。 已定义作为seq
的补充:
(defn empty? [coll]
(not (seq coll)))
我将您的功能重写为
(defn one-element? [coll]
(and (seq coll)
(empty? (rest coll))))
或
(defn one-element [coll]
(and (seq coll)
(not (next coll))))
这些速度与seq
和rest
/ next
的速度顺序相同。