Actually, what I'm looking for is a way to use arbitrary types of keys 
rather than integers.

I have this so far:

;;;; Table data structure.
;;;; For now, the table data structure is a map of maps.

(defn row
  "Get a row of the table.
 If only the key is passed, a row
lookup function is returned."
  ([r]
     #(row r %))
  ([r m]
     (get m r)))

(defn col
  "Get a column of the table."
  ([c]
     #(col c %))
  ([c m]
     (for [[rk r] m
           :let [x (get r c)]
           :when x]
       [rk x])))

(defn t-get
  "Get values in a table."
  [m &{:keys [r c]}]
  (cond
   (and r c) (get-in m [r c])
   r (row r m)
   c (col c m)
   :else m))

(defn t-update
  "Update a value or values in the map."
  [m f &{:keys [r c]}]
  (cond
   (and r c) (update-in m [r c] f)
   r (update-in m [r] f)
   
   ;; This O(n) column update is making me angry!
   c (let [res (f (into {} (t-get m :c c)))]
       (println "f result: " res)
       (reduce
        (fn [acc k]
          (if-let [v (get res k)]
            (update-in acc [k] assoc c v)
            (if (contains? (get m k) c)
              (update-in acc [k] dissoc c)
              acc)))
        m
        (clojure.set/union (set (keys m))
                           (set (keys res)))))))

(defn t-set
  "Set a value or values in the map."
  [m v & r]
  (apply t-update m (constantly v) r))

It works pretty well for swapping out rows or individual cells, but setting 
a column seems like an inefficient operation.  I don't know how much I'll be
using that.

On Thursday, 1 August 2013 17:59:40 UTC-7, JvJ wrote:
>
> I'm looking for an associative data structure that can be accessed by both 
> rows and columns, and could potentially be sparse.
>
> Suppose the following table is called t:
>
> |   | :A   | :B   | :C       ||---+------+------+----------|| 1 |      |      
> | '[x y z] || 2 | "2a" | "2b" |          || 3 |      |      |          || 3 | 
> :3a  |      | "Foo"    |
>
>
> Then (t :A) would return {2 "2a", 3 :3a}, and (t 2) would return {:A "2a", 
> :B "2b"}.
> (t :A 2) or (t 2 :A) would return "2a".
>
> I'm thinking of implementing it as a simple map of maps with some extra 
> functions, but I'm not sure if
> that would be the best option.
>
>
>

-- 
-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to