Yesterday I need a similar function (interleave, but don't stop when 
the shortest seq ends), so I wrote it. I subsequently refactored the 
program and didn't need it anymore, but here it is anyway. It could 
probably be written more succinctly, but I followed the implementation 
of core/interleave.

(defn interleave-all
   "Like interleave, but stops when the longest seq is done, instead of 
the shortest."
   ([c1 c2]
    (lazy-seq
      (let [s1 (seq c1)
            s2 (seq c2)]
        (cond
          (and s1 s2) ; there are elements left in both
          (cons (first s1) (cons (first s2)
                                 (interleave-all (rest s1) (rest s2))))

          s1 ; s2 is done
          s1

          s2 ; s1 is done
          s2))))
   ([c1 c2 & colls]
    (lazy-seq
      (let [ss (filter identity
                       (map seq
                            (conj colls c2 c1)))]
        (concat (map first ss)
                (apply interleave-all (map rest ss)))))))

Usage (commas are mine):
user=> (interleave-all [1 2 3 4 5] '[a b c d e f g h i])
(1 a, 2 b, 3 c, 4 d, 5 e, f, g, h, i)
user=> (interleave-all [1 2 3 4 5] '[a b c d e f g h i] '[A B])
(1 a A, 2 b B, 3 c 4, d 5, e, f, g, h, i)
It is still lazy:
user=> (take 50 (interleave-all [1 2 3 4 5] '[a b c d e f g h i] '[A B 
C D E F G H I J K L] (iterate inc 0)))
(1 a A 0, 2 b B 1, 3 c C 2, 4 d D 3, 5 e E 4, f F 5, g G 6, h H 7, i I 
8, J 9, K 10, L 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23)

Alex

On 2009-11-19 20:13:28 -0500 John Harrop <jharrop...@gmail.com> wrote:

> On Thu, Nov 19, 2009 at 7:51 PM, Alex Osborne <a...@meshy.org> wrote:
> 
>> John Harrop wrote:
>>>     This is just (sort (concat [1 2 3 4 5 6 7] [3 2 7])) though.
>>> 
>>> 
>>> I think he also wants the original order of the first input coll to 
>>> be
>>> preserved, though. Sort wouldn't do that.
>> 
>> Hmmm.. that's a pretty weird set of requirements.  Usually a
>> multiset/bag is unordered.  What happens if same elements aren't 
>> grouped
>> together in the first input coll it, it just arbitrarily picks one of
>> their positions and moves them all together there? :-)
>> 
>> If you're going to go to the trouble of making special multiset
>> functions you may as well create a new multiset collection type that
>> does the "right thing" when you conj to it and such.  It is also 
>> means
>> you can store things in a way that allows efficient implementation of
>> the operations, instead of just hoping the library user passes data 
>> in
>> the right order or using slow but safe n^2 or n log n algorithms
>> everywhere.
> 
> 
> I don't disagree. We'll have to wait for the original poster to 
> clarify his
> requirements.
> 

-- 
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

Reply via email to