core: multi-collection map handles nil elements in a lazy-seq input (jolt-dzh)
The multi-coll map step detected end-of-seq with (nil? (ls-first cur)), which also fired on a legitimate nil element — so mapping over a lazy-seq containing nils truncated at the first nil. That's why (doall (map merge a b)) collapsed to () as a reduce accumulator. Use seq-done? to detect exhaustion and push the value (which may be nil). doall is unchanged; clojure.data restored to the canonical (doall (map ...)) form. Conformance 218/218; battery 3919.
This commit is contained in:
parent
e623968b45
commit
bfb49f23ab
2 changed files with 13 additions and 13 deletions
|
|
@ -44,18 +44,15 @@
|
|||
"Diff associative things a and b, comparing only keys in ks."
|
||||
[a b ks]
|
||||
(reduce
|
||||
;; mapv (eager) rather than the reference's (doall (map …)): jolt's
|
||||
;; multi-collection map is lazy and doesn't force reliably as a reduce
|
||||
;; accumulator here.
|
||||
(fn [diff1 diff2] (mapv merge diff1 diff2))
|
||||
(fn [diff1 diff2] (doall (map merge diff1 diff2)))
|
||||
[nil nil nil]
|
||||
(mapv (partial diff-associative-key a b) ks)))
|
||||
(map (partial diff-associative-key a b) ks)))
|
||||
|
||||
(defn- diff-sequential [a b]
|
||||
(vec (mapv vectorize (diff-associative
|
||||
(if (vector? a) a (vec a))
|
||||
(if (vector? b) b (vec b))
|
||||
(range (max (count a) (count b)))))))
|
||||
(vec (map vectorize (diff-associative
|
||||
(if (vector? a) a (vec a))
|
||||
(if (vector? b) b (vec b))
|
||||
(range (max (count a) (count b)))))))
|
||||
|
||||
(defn- diff-set [a b]
|
||||
[(not-empty (set/difference a b))
|
||||
|
|
|
|||
|
|
@ -834,12 +834,15 @@
|
|||
(while (< i (length cs))
|
||||
(let [cur (in cs i) ridx (in idxs i) real (in reals i)]
|
||||
(if (not (nil? cur))
|
||||
(let [val (ls-first cur)]
|
||||
(if (nil? val) (do (set ok false) (break))
|
||||
(do (array/push args val)
|
||||
# Detect exhaustion with seq-done?, NOT (nil? (ls-first)): a
|
||||
# lazy-seq can legitimately contain nil elements, and treating the
|
||||
# first nil as end-of-seq truncates (e.g. mapping over a previous
|
||||
# map result that holds nils).
|
||||
(if (seq-done? cur) (do (set ok false) (break))
|
||||
(do (array/push args (ls-first cur))
|
||||
(put next-cs i (ls-rest cur))
|
||||
(put next-idxs i (+ ridx 1))
|
||||
(put next-reals i nil))))
|
||||
(put next-reals i nil)))
|
||||
(let [c (if (nil? real)
|
||||
(let [rc (realize-for-iteration (in colls i))]
|
||||
(put next-reals i rc) rc)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue