I am going to implement all of the array methods from the JavaScript prelude. First of all here is the mutator methods:
(swap! coll rest)
(swap! coll butlast)
(swap! coll concat [1])
(swap! coll (partial concat [1]))
(swap! coll reverse)
(swap! coll (partial sort <))
The only one that really requires special attention is splice.
(defn splice
[coll start-index how-many & insertions]
(let [start-coll (map coll (range 0 start-index))
end-coll (map coll (range (+ start-index how-many) (count coll)))]
(concat start-coll insertions end-coll)))
The accessor method concat is already implemented in Clojure, and here is the rest of the methods:
(defn join
[coll separator]
(cond
(empty? coll) ""
(= (count coll) 1) (str (first coll))
:else (str (first coll) separator (join (rest coll) separator))))
(defn to-string
[coll]
(join coll ","))
(defn to-source
[coll]
(str "[" (join coll ", ") "]"))
(defn slice
[coll start end]
(map coll (range start end)))
(defn index-of
[coll elt]
(cond
(nil? ((set coll) elt)) -1
(= (first coll) elt) 0
:else (inc (index-of (rest coll) elt))))
(defn last-index-of
[coll elt]
(- (dec (count coll)) (index-of (reverse coll) elt)))
The methods, filter, map, some, every?, and reduce are already implemented in clojure. The only thing we don't really have already is for-each. This can be implemented as a macro that uses the loop primitive.
(defmacro for-each
[coll func]
(let [i (gensym)]
`(loop [~i 0]
(when-not (= ~i (count ~coll))
(do
(~func (nth ~coll ~i))
(recur (inc ~i)))))))
This function is actually quite useful, for example we can use it print out elements of a list:
(for-each [1 2 3 4 5] prn)
No comments:
Post a Comment