On 8/2/13 8:08 PM, JvJ wrote:
> 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.
>>
>>
>>
> 

please, please, use clojure.set/index, it does what you want, better the
code you shared.

-- 
And what is good, Phaedrus,
And what is not good—
Need we ask anyone to tell us these things?

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to