Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clojure: finding out if a collection is seq-able

So there's list?, seq?, vector?, map? and so on to determine what type of collection the argument is.

What's a good way of telling the difference between

  • a map (i.e. something that contains key-value pairs)
  • a collection (i.e. something that contains values)
  • a non collection value like a string.

Is there a better way than

#(or (seq? %) (list? %) etc)
like image 956
Kurt Schelfthout Avatar asked Oct 25 '10 22:10

Kurt Schelfthout


People also ask

What is SEQ in Clojure?

Clojure defines many algorithms in terms of sequences (seqs). A seq is a logical list, and unlike most Lisps where the list is represented by a concrete, 2-slot structure, Clojure uses the ISeq interface to allow many data structures to provide access to their elements as sequences.

What is the difference between a sequence and a collection?

Sequences don't use inline functions, therefore, new Function objects are created for each operation. On the other hand, collections create a new list for every transformation while sequences just keep a reference to the transformation function.

Is a sequence a collection?

"Collection" and "Sequence" are abstractions, not a property that can be determined from a given value. Collections are bags of values. Sequence is a data structure (subset of collection) that is expected to be accessed in a sequential (linear) manner.

What is a collection in Clojure?

Clojure collections "collect" values into compound values. There are four key Clojure collection types: vectors, lists, sets, and maps. Of those four collection types, vectors and lists are ordered.


2 Answers

using seq? is about as concise and clean as it gets.

clojure.contrib.core defines:

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

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

it does what you proposed with one big or statement of

  • already a seq
  • an instance of clojure.lang.Seqable
  • nil
  • instance of Iterable
  • an array
  • a string
  • instance of java.util.Map
like image 148
Arthur Ulfeldt Avatar answered Sep 28 '22 08:09

Arthur Ulfeldt


Let's not forget about sequential?:

user=> (sequential? [])
true
user=> (sequential? '())
true
user=> (sequential? {:a 1})
false
user=> (sequential? "asdf")
false
like image 37
staafl Avatar answered Sep 28 '22 08:09

staafl