0

Is there a way in Clojure to test a vector and see if it's nested, i.e. a way to test [:a :b :c :d] vs. [[:a :b] [:c :d]]?

I've tried the test

(vector? [:a :b :c :d])
 true

but it remains true for nested vectors as well,

(vector? [[:a :b] [:c :d]])
 true
sunspots
  • 1,047
  • 13
  • 29

2 Answers2

0

checking if any of them are sequential seems close:

user> (every? #(not (sequential? %)) [:a :b :c :d])
true
user> (every? #(not (sequential? %)) [:a :b :c :d [:e]])
false

because all the base collections can be made into sequences, though it may be necessary to also check for Java arrays:

(every? #(not (sequential? %)) [:a :b :c :d (into-array [1 2 3])])
Arthur Ulfeldt
  • 90,827
  • 27
  • 201
  • 284
  • `(every? #(not (f %)) coll)` should really be `(not-any? f coll)`. – amalloy Nov 23 '13 at 05:54
  • @Arthur This is partially related as I have used the code you wrote above. Is there a clear way to iterate the code segment after `:else`? The goal is to be able to drill n levels deep into a collection. `(defn test-func [x f] (cond (every? #(not (sequential? %)) x) (apply f x) :else (map #(apply f %) x)))` – sunspots Nov 23 '13 at 06:03
0

vector? returns true if its argument is a vector (implements IPersistentVector). [:a :b :c :d] is a vector. So is [[:a :b] [:c :d]]. Therefore, calling vector? on either of them will return true.

Now, we can say a vector is nested if any of its elements is a vector. We can test for this using some and the vector? predicate:

(defn nested-vector? [v]
  (some vector? v))

This will test specifically for vectors. However, you might want to take a more general approach that applies to any Sequential data structure:

(defn nested? [coll]
  (some sequential? coll))
Nathan Davis
  • 5,636
  • 27
  • 39