Clojure:找出一个集合是否可以选择

时间:2010-10-25 22:00:29

标签: clojure clojureclr

所以有列表?,seq?,vector ?, map?等等,以确定论证的收集类型。

什么是区分

的好方法
  • 地图(即包含键值对的内容)
  • 一个集合(即包含值的东西)
  • 像字符串一样的非集合值。

有没有比

更好的方法
#(or (seq? %) (list? %) etc)

4 个答案:

答案 0 :(得分:9)

使用seq?

简洁明了。

clojure.contrib.core定义:

seqable?
    function
    Usage: (seqable? x)
    Returns true if (seq x) will succeed, false otherwise.

http://clojure.github.com/clojure-contrib/core-api.html

它使用

的一个大or语句执行您的建议
  • 已经是seq
  • clojure.lang.Seqable
  • 的一个实例
  • Iterable实例
  • 一个数组
  • 一个字符串
  • java.util.Map的实例

答案 1 :(得分:4)

现在,函数seq仅执行此操作:

(. clojure.lang.RT (seq coll))

在最新版Clojure的RT.java中,你会发现:

static public ISeq seq(Object coll){
    if(coll instanceof ASeq)
        return (ASeq) coll;
    else if(coll instanceof LazySeq)
        return ((LazySeq) coll).seq();
    else
        return seqFrom(coll);
}

static ISeq seqFrom(Object coll){
    if(coll instanceof Seqable)
        return ((Seqable) coll).seq();
    else if(coll == null)
        return null;
    else if(coll instanceof Iterable)
        return IteratorSeq.create(((Iterable) coll).iterator());
    else if(coll.getClass().isArray())
        return ArraySeq.createFromObject(coll);
    else if(coll instanceof CharSequence)
        return StringSeq.create((CharSequence) coll);
    else if(coll instanceof Map)
        return seq(((Map) coll).entrySet());
    else {
        Class c = coll.getClass();
        Class sc = c.getSuperclass();
        throw new IllegalArgumentException("Don't know how to create ISeq from: " + c.getName());
    }
}

ASeqLazySeq已经是seq。 Seqable是知道如何返回自身序列的东西。

这样就留下了Java核心类,它们应该是可选的,但是Clojure不能改变它来添加seq方法。这些目前已被硬编码到此列表中。如果有一天实现改变了,可能会使用协议来扩展Java核心类,我不会感到惊讶吗?

答案 2 :(得分:4)

我们不要忘记sequential?

user=> (sequential? [])
true
user=> (sequential? '())
true
user=> (sequential? {:a 1})
false
user=> (sequential? "asdf")
false

答案 3 :(得分:0)

所有seqable都实现了clojure.lang.Seqable标记:

(instance? clojure.lang.Seqable x)

Clojure 1.9提供seqable?