Reputation:
I'm have a following structure:
(defrecord Member [id name salary role])
(defrecord Project [id name duration])
(defrecord ProjectMember [project member])
(def project-member-records (ref ()))
(defn find-project-member-record [parm-proj-id parm-member-id]
(filter #(let [project (.project %)
member (.member %)
proj-id (:id project)
member-id (:id member)]
(and (= proj-id parm-proj-id)
(= member-id parm-member-id))) @project-member-records))
;;Sample func, does not work
(defn remove-project-member-record [proj-id member-id]
(dosync (ref-set project-member-records (remove #(= (:id (.project %)) proj-id) @project-member-records))))
Now, i want to remove item from project-member-records
. For instance, i want to remove item by project id and member id, like i'm finding record in find-project-member-record
function. Or (and) i want remove item than i have record found by project-member-records
, something like (remove (find-project-member-record 1 1) project-records) ;pseudo code
But i dont know how i can do this.
Upvotes: 0
Views: 146
Reputation: 2600
Using remove
is correct, but find-project-member-record
returns a sequence. Try
(defn remove-project-member-record [proj-id member-id]
(let [it (first (find-project-member-record proj-id member-id))]
(dosync
(ref-set project-member-records
(remove #(= % it) @project-member-records)))))
If find-project-member-record
always returns either an empty sequence or a sequence with one item, it may make sense for it to instead return either the item itself or nil
. (e.g., call first
on the result of filter
in find-project-member-record
rather than in remove-project-member-record
and elsewhere).
Here's how you can structure it if you want everything to be wrapped in the dosync
transaction:
(defn remove-project-member-record [proj-id member-id]
(dosync
(let [it (first (find-project-member-record proj-id member-id))]
(ref-set project-member-records
(remove #(= % it) @project-member-records)))))
Upvotes: 1