On 2 February 2010 00:18, Meikel Brandmeyer <m...@kotka.de> wrote: > Consider this (admittedly constructed) case: > (get-in {:a {:b 1}} [:x :c] {:c :uhoh})
Excellent point! > Or to use butlast/last instead of peek/pop. I think this is the best approach. butlast/last have linear time so the overhead is small. There are still some sharp edges I'm not sure about: (A) user=> (get-in {:a 1} []) {:a 1} ;; this is existing behavior, but I feel the result should be nil (B) user=> (get-in {:a 1} nil) {:a 1} ;; this is existing behavior, but I feel the result should be nil (nil is a seq so not an exception) (C) user=> (get-in {:a 1} 5) java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Integer (NO_SOURCE_FILE:0) ;; existing behavior, seems sensible to throw an exception here rather than return nil (D) user=> (get-in {nil {:a 1}} [] 2) {:a 1} ;; new behavior ;; using last/butlast only -> this is wrong... need to check the seq size ;; the solution depends upon what is correct for the preceding cases so need to establish those first Alternatively one could take the view that [] and nil are illegal key sequences, in which case should get-in enforce that (via preconditions or just a check) or should it just be added to the doc-string that using those values is undefined, or both? I've marked the ticket back to new in the meantime... will update once resolved. For reference here is a version that behaves most like existing get-in: (defn get-in "Returns the value in a nested associative structure, where ks is a sequence of keys. Returns nil if the key is not present, or the not-found value if supplied." ([m ks] (reduce get m ks)) ([m ks not-found] (if (empty? ks) m (if-let [l (reduce get m (butlast ks))] (get l (last ks) not-found) not-found)))) I'm not convinced returning the map when given an empty key sequence is the right thing to do, I'd prefer it to return nil or throw an exception in both arity cases. Regards, Tim. -- 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