Started work on *safe-sparse-operations*
Not fully working yet
This commit is contained in:
parent
d430937c56
commit
9d2b6da1cc
|
@ -1,5 +1,7 @@
|
||||||
(ns sparse-array.core)
|
(ns sparse-array.core)
|
||||||
|
|
||||||
|
(def ^:dynamic *safe-sparse-operations* false)
|
||||||
|
|
||||||
(defn make-sparse-array
|
(defn make-sparse-array
|
||||||
"Make a sparse array with these `dimensions`. Every member of `dimensions`
|
"Make a sparse array with these `dimensions`. Every member of `dimensions`
|
||||||
must be a keyword; otherwise, `nil` will be returned."
|
must be a keyword; otherwise, `nil` will be returned."
|
||||||
|
@ -18,22 +20,37 @@
|
||||||
"`true` if `x` is a sparse array conforming to the conventions established
|
"`true` if `x` is a sparse array conforming to the conventions established
|
||||||
by this library, else `false`."
|
by this library, else `false`."
|
||||||
([x]
|
([x]
|
||||||
(and
|
(apply
|
||||||
(map? x)
|
sparse-array?
|
||||||
(pos? (:dimensions x))
|
(cons
|
||||||
(keyword? (:coord x))
|
x
|
||||||
(if
|
(cons
|
||||||
(coll? (:content x))
|
(:coord x)
|
||||||
(every?
|
(if
|
||||||
sparse-array?
|
(coll? (:content x))
|
||||||
(map #(x %) (filter integer? (keys x))))
|
(:content x))))))
|
||||||
(= (:content x) :data)))))
|
([x & axes]
|
||||||
|
(and
|
||||||
|
(map? x)
|
||||||
|
(pos? (:dimensions x))
|
||||||
|
(keyword? (:coord x))
|
||||||
|
(= (:coord x) (first axes))
|
||||||
|
(if
|
||||||
|
(rest axes)
|
||||||
|
(and
|
||||||
|
(= (:content x) (rest axes))
|
||||||
|
(every?
|
||||||
|
sparse-array?
|
||||||
|
(map #(x %) (filter integer? (keys x)))))
|
||||||
|
(= (:content x) :data)))))
|
||||||
|
|
||||||
(defn put
|
(defn put
|
||||||
"Return a sparse array like this `array` but with this `value` at these
|
"Return a sparse array like this `array` but with this `value` at these
|
||||||
`coordinates`. Returns `nil` if any coordinate is invalid."
|
`coordinates`. Returns `nil` if any coordinate is invalid."
|
||||||
[array value & coordinates]
|
[array value & coordinates]
|
||||||
(if
|
(cond
|
||||||
|
(and *safe-sparse-operations* (sparse-array? array))
|
||||||
|
(throw (ex-info "Sparse array expected" {:array array}))
|
||||||
(every?
|
(every?
|
||||||
#(and (integer? %) (or (zero? %) (pos? %)))
|
#(and (integer? %) (or (zero? %) (pos? %)))
|
||||||
coordinates)
|
coordinates)
|
||||||
|
@ -49,7 +66,13 @@
|
||||||
(or
|
(or
|
||||||
(array (first coordinates))
|
(array (first coordinates))
|
||||||
(apply make-sparse-array (:content array)))
|
(apply make-sparse-array (:content array)))
|
||||||
(cons value (rest coordinates))))))))
|
(cons value (rest coordinates))))))
|
||||||
|
*safe-sparse-operations*
|
||||||
|
(throw
|
||||||
|
(ex-info
|
||||||
|
"Coordinates must be zero or positive integers"
|
||||||
|
{:coordinates coordinates
|
||||||
|
:invalid (remove integer? coordinates)}))))
|
||||||
|
|
||||||
(defn get
|
(defn get
|
||||||
"Return the value in this sparse `array` at these `coordinates`."
|
"Return the value in this sparse `array` at these `coordinates`."
|
||||||
|
|
|
@ -4,7 +4,21 @@
|
||||||
|
|
||||||
(deftest creation-and-testing
|
(deftest creation-and-testing
|
||||||
(testing "Creation and testing."
|
(testing "Creation and testing."
|
||||||
(is (sparse-array? (make-sparse-array :x :y :z)))))
|
(is (sparse-array? (make-sparse-array :x :y :z)))
|
||||||
|
(is (sparse-array? {:dimensions 2,
|
||||||
|
:coord :x,
|
||||||
|
:content '(:y),
|
||||||
|
3 {:dimensions 1,
|
||||||
|
:coord :y,
|
||||||
|
:content :data,
|
||||||
|
4 "hello"},
|
||||||
|
4 {:dimensions 1,
|
||||||
|
:coord :y,
|
||||||
|
:content :data,
|
||||||
|
3 "goodbye"}}))
|
||||||
|
(is-not (sparse-array? []))
|
||||||
|
(is-not (sparse-array? "hello"))
|
||||||
|
))
|
||||||
|
|
||||||
(deftest put-and-get
|
(deftest put-and-get
|
||||||
(testing "get"
|
(testing "get"
|
||||||
|
@ -84,9 +98,17 @@
|
||||||
[nil nil nil nil nil]
|
[nil nil nil nil nil]
|
||||||
[nil nil nil nil "hello"]
|
[nil nil nil nil "hello"]
|
||||||
[nil nil nil "goodbye" nil]]
|
[nil nil nil "goodbye" nil]]
|
||||||
actual (sparse-to-dense (put
|
actual (sparse-to-dense {:dimensions 2,
|
||||||
(put
|
:coord :x,
|
||||||
(make-sparse-array :x :y)
|
:content '(:y),
|
||||||
"hello" 3 4)
|
3 {:dimensions 1,
|
||||||
"goodbye" 4 3))]
|
:coord :y,
|
||||||
|
:content :data,
|
||||||
|
4 "hello"},
|
||||||
|
4 {:dimensions 1,
|
||||||
|
:coord :y,
|
||||||
|
:content :data,
|
||||||
|
3 "goodbye"}})]
|
||||||
(is (= actual expected)))))
|
(is (= actual expected)))))
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue