3

I'd like to write a function that takes vectors [& x] and applies a test to pairs of elements. Outputting a vector of elements the test deemed identical and a vector of nil elements.

My first thought is to take the vectors and flatten them.

(defn soup [& x]
    (vec (flatten x))

Then apply a test such as identical? neg? or something along those lines. It's at the point of pattern matching that I am stuck in trying to assemble the output.

Ex) Input 1: [:a :b :c :a :b :c]

Output 1: [[:a :a] [:b :b] [:c :c]]

Input 2: [[:a :b :c] [:a :b :c]]

Output 2: [[[:a :b :c] [:a :b :c]]]

If Input 2 is first flattened, it gives back Output 1.

sunspots
  • 1,047
  • 13
  • 29
  • Hi @Alex, can you provide an output example? – tangrammer Nov 20 '13 at 19:37
  • flatten is almost never what you want; (soup :a :b :c), (soup [:a] [:b :c]), (soup [:a :b] :c), and (soup [[[:a :b :c]]]) would all return the same result based on that definition – noisesmith Nov 20 '13 at 22:00

1 Answers1

4

Would combining sort and partition-by be close to what you are asking for?

(->> [:a :b :c :a :b :c] sort (partition-by identity))
((:a :a) (:b :b) (:c :c)) 

(->> [[:a :b :c] [:a :b :c]] sort (partition-by identity))
(([:a :b :c] [:a :b :c]))

and if you need them to be vectors after:

(->> [:a :b :c :a :b :c] sort (partition-by identity) (map vec) vec)
[[:a :a] [:b :b] [:c :c]]

(->> [[:a :b :c] [:a :b :c]] sort (partition-by identity) (map vec) vec)
[[[:a :b :c] [:a :b :c]]]
Arthur Ulfeldt
  • 90,827
  • 27
  • 201
  • 284
  • How would you modify this code to take a vector such as [:a :a :b :b :b :c :c :c :a :a] and output [[:a :a] [:b :b :b] [:c :c :c] [:a :a]. Whereby runs of identical elements of the input are output as vectors. – sunspots Nov 20 '13 at 21:40
  • just remove the call to sort. – Arthur Ulfeldt Nov 20 '13 at 21:56