Clojure序列长度

33

我敢肯定之前我的 alength 是可以用的,但是现在我不太清楚我哪里出了问题:

user=> (alength '(1 2 3))
IllegalArgumentException No matching method found: alength  clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:79)
user=> (alength [1 2 3])
IllegalArgumentException No matching method found: alength  clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:79)
user=> (doc alength)
-------------------------
clojure.core/alength
([array])
  Returns the length of the Java array. Works on arrays of all
  types.
nil

在Clojure中,我应该如何获取列表/数组的长度?

5个回答

52

可以尝试使用count函数:

(count '(1 2 3))
=> 3
(count [1 2 3])
=> 3

36

正如文档字符串所述,alength 适用于 Java™ 数组,例如 String[]Integer[],这绝对是与 Clojure 列表或向量不兼容的类型,你应该使用 count

user=> (def x '(1 2 3))
#'user/x
user=> (def xa (to-array x))
#'user/xa
user=> (class x)
clojure.lang.PersistentList
user=> (class xa)
[Ljava.lang.Object;
user=> (alength xa)
3
user=> (alength x) 
java.lang.IllegalArgumentException: No matching method found: alength (NO_SOURCE_FILE:0)
user=> (count x)
3

[Ljava.lang.Object; 是对于本地 Object 数组输出的奇怪方式,由 toString 定义


5
请注意,count 命令也适用于数组。 只有在速度至关重要的代码中,您已经知道自己拥有一个数组并且需要直接访问时,才需要使用 alength 命令。在这种情况下,使用 count 命令会更慢,因为它更通用。 - kotarak

14

应该使用count函数。

user=> (count '(1 2 3))
3

2
你可以使用递归方式来做到这一点:
(defn length
 [list]
 (if (empty? list) 0
  (+ 1 (length (rest list)))))

希望这可以帮到你!

2
这可能有些过度,但你可以像 Common LISP 的 length 函数一样模仿它,就像这样:

(def length 
 (fn [lst]
  (loop [i lst cnt 0]
   (cond (empty? i) cnt
     :t (recur (rest i)(inc cnt))))))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接