Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Idiomatically iterating over a 2 (or higher) dimensional sequence in Clojure

Tags:

clojure

Is there a 'proper' way to iterate over a two-dimensional sequence in Clojure? Suppose I had a list of lists of numbers, like this

 ((1 2 3)
  (4 5 6)
  (7 8 9))

and I wanted to generate a new list of lists with each number incremented by one. Is there an easy way to do this in Clojure without relying on nested maps or loop/recurs? I've been able to do it, but my solutions are ugly and I find them difficult to understand when I re-read them.

Thanks

like image 803
Joel Avatar asked Nov 11 '11 02:11

Joel


2 Answers

What you describe is precisely what clojure.walk is for:

(def matrix [[1 2 3]
             [4 5 6]
             [7 8 9]])
(use 'clojure.walk :only [prewalk])
(prewalk #(if (number? %) (inc %) %) matrix)
=> [[2 3 4] [5 6 7] [8 9 10]]

Note 1: it is idiomatic to use vectors instead of parentheses for literal sequential collections.

Note 2: walk preserves type.

like image 136
Alex Taggart Avatar answered Sep 26 '22 20:09

Alex Taggart


You can always just use a list comprehension. I find myself using them quite often coming from an imperative background so I don't know how idiomatic it is. In your specific case, you can do:

(for [my-list my-matrix] (map inc my-list))
like image 40
Sean Nilan Avatar answered Sep 23 '22 20:09

Sean Nilan