Arrays in Clojure

In Clojure, a vector is a commonly used data structure that is similar to an array. Unlike arrays in some languages, Clojure vectors are immutable and can grow or shrink in size.

(ns arrays-example
  (:require [clojure.pprint :refer [pprint]]))

(defn main []
  ;; Create a vector 'a' with 5 elements, all initialized to 0
  (let [a (vec (repeat 5 0))]
    (println "emp:" a)

    ;; Set a value at an index using assoc
    (let [a (assoc a 4 100)]
      (println "set:" a)
      (println "get:" (get a 4)))

    ;; The count function returns the length of a vector
    (println "len:" (count a))

    ;; Create and initialize a vector in one line
    (let [b [1 2 3 4 5]]
      (println "dcl:" b))

    ;; In Clojure, vectors automatically grow as needed
    (let [b [1 2 3 4 5]]
      (println "dcl:" b))

    ;; To create a vector with specific elements at specific indices,
    ;; you can use vec and assoc
    (let [b (-> (vec (repeat 5 0))
                (assoc 0 100)
                (assoc 3 400)
                (assoc 4 500))]
      (println "idx:" b))

    ;; Create a 2D vector
    (let [two-d (vec (repeat 2 (vec (repeat 3 0))))]
      (let [two-d (reduce (fn [acc i]
                            (reduce (fn [acc j]
                                      (assoc-in acc [i j] (+ i j)))
                                    acc
                                    (range 3)))
                          two-d
                          (range 2))]
        (println "2d:" two-d)))

    ;; Create and initialize a 2D vector at once
    (let [two-d [[1 2 3]
                 [1 2 3]]]
      (println "2d:" two-d))))

(main)

Note that vectors in Clojure are printed in the form [v1 v2 v3 ...] when using println.

To run the program, save it as arrays_example.clj and use the clj command:

$ clj arrays_example.clj
emp: [0 0 0 0 0]
set: [0 0 0 0 100]
get: 100
len: 5
dcl: [1 2 3 4 5]
dcl: [1 2 3 4 5]
idx: [100 0 0 400 500]
2d: [[0 1 2] [1 2 3]]
2d: [[1 2 3] [1 2 3]]

In Clojure, vectors are more flexible than traditional arrays. They can grow dynamically and are immutable, meaning each operation returns a new vector instead of modifying the original. The assoc and assoc-in functions are used to “update” vectors by creating new ones with the specified changes.

For multi-dimensional structures, we use nested vectors. The reduce function is used to iterate over the indices and create the 2D structure, which is a common functional programming approach in Clojure.