【问题标题】:Clojure: finding out if a collection is seq-ableClojure:找出一个集合是否可以排序
【发布时间】:2010-10-25 22:00:28
【问题描述】:

所以有 list?, seq?, vector?, map?等等来确定参数是什么类型的集合。

什么是区分两者的好方法

  • 一个映射(即包含键值对的东西)
  • 一个集合(即包含值的东西)
  • 非集合值,如字符串。

有没有比

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

【问题讨论】:

    标签: clojure clojureclr


    【解决方案1】:

    使用seq? 会尽可能简洁明了。

    clojure.contrib.core 定义:

    可排序的? 功能 用法:(seqable?x) 如果 (seq x) 成功则返回 true,否则返回 false。

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

    它通过一个大的or 声明来满足您的建议

    • 已经有序列了
    • clojure.lang.Seqable 的一个实例
    • Iterable 实例
    • 一个数组
    • 一个字符串
    • java.util.Map 的实例

    【讨论】:

    【解决方案2】:

    别忘了sequential?

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

    【讨论】:

      【解决方案3】:

      函数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 核心类?

      【讨论】:

        【解决方案4】:

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

        (instance? clojure.lang.Seqable x)
        

        Clojure 1.9 提供seqable?

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-12-11
          • 2015-10-09
          • 1970-01-01
          相关资源
          最近更新 更多