Re: Function that "weaves" two collections together - looking for feedback

2014-02-19 Thread Steve Miner
On Feb 19, 2014, at 12:28 AM, Laurent Droin  wrote:

> Ah, thank you. "interleave" is what I was looking for. I looked for "weave", 
> "zip", "map", "concat", and all the "see also" but did not find "interleave".
> Interleave will of course not handle the last value in the categories 
> collection so my first instinct will be to call (into [] ) on the map 
> returned by interleave, and to add (using conj) the (last categories) to the 
> vector. Not sure whether there is a better way.

Here's an interleave-all function that's like interleave but uses all the 
elements of all the collections.  Be careful if any of your collections might 
be infinite.  In that case, you need to wrap something like `take` around the 
call.

(defn interleave-all
  "Returns a lazy seq of the first item in each collection, then the second, 
etc.  If one 
collection ends, continues to interleave the others.  Naturally, you should 
take care with
infinite sequences."
  ([] (lazy-seq nil))
  ([c] (lazy-seq c))

  ([c1 c2]
 (lazy-seq
  (cond (not (seq c1)) c2
(not (seq c2)) c1
:else (conj (interleave-all (rest c1) (rest c2)) (first c2) (first 
c1)

  ([c1 c2 & colls] 
 (lazy-seq 
  (let [ss (keep seq (conj colls c2 c1))]
(concat (map first ss) (apply interleave-all (map rest ss)))



-- 
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
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: Function that "weaves" two collections together - looking for feedback

2014-02-18 Thread Mark Engelberg
(concat sequence [val])

would often be preferable to

(conj (into [] sequence) val)

because the former solution maintains laziness.


On Tue, Feb 18, 2014 at 9:28 PM, Laurent Droin wrote:

> Ah, thank you. "interleave" is what I was looking for. I looked for
> "weave", "zip", "map", "concat", and all the "see also" but did not find
> "interleave".
> Interleave will of course not handle the last value in the categories
> collection so my first instinct will be to call (into [] ) on the map
> returned by interleave, and to add (using conj) the (last categories) to
> the vector. Not sure whether there is a better way.
>
>
> On Tuesday, February 18, 2014 9:17:54 PM UTC-8, Michael Gardner wrote:
>
>> You may be interested in the core function 'interleave'. As for (into
>> []), it's perfectly idiomatic as long as you actually need to return a
>> vector and not just some kind of sequence (the more common case). But note
>> also the mapv/filterv/reduce-kv family of functions, though they're not
>> directly applicable here.
>>
>> On Feb 18, 2014, at 22:58 , Laurent Droin  wrote:
>>
>> > Hi,
>> >
>> > Continuing my little pet project (small program really) to learn
>> Clojure, I am now working on a function whose description would be
>> something like:
>> >   "Returns a collection 'weaving' 2 collections (boundaries into
>> categories).
>> >   Boundaries must have one element less than categories.
>> >   For example, if categories is [:z1 :z2 :z3 :z4 :z5]
>> >   and boundaries is [120 150 165 180]
>> >   returns [:z1 120 :z2 150 :z3 165 :z4 180 :z5]"
>> >
>> > Assume the precondition is enforced.
>> > If categories has n elements, boundaries has n-1.
>> >
>> > I have tried to come up with a good implementation. I actually came up
>> with two, one that is non recursive, and one that is recursive. But I'm not
>> fully satisfied. I have the feeling that it's possible to make the function
>> simpler, and more elegant but I only know a subset of Clojure and am surely
>> missing some good idioms that I could/should be using.
>> > So once again, relying on feedback from experienced Clojurists to show
>> me the way :-)
>> >
>> > Here is what I have so far:
>> >
>> > 1- the non recursive function - based on mapcat
>> > (defn build-quantize-defs
>> >
>> >
>> > [categories boundaries]
>> >
>> >
>> > (conj (into [] (mapcat #(vector %1 %2) categories boundaries)) (last
>> categories)))
>> >
>> > 2 - the recursive function
>> > (defn build-quantize-defs-recur [categories boundaries]
>> >
>> >
>> > (let [c (first categories) b (first boundaries)]
>> >
>> >
>> > (if (nil? b)
>> >
>> >
>> > [c]
>> >
>> >
>> > (into [] (concat [c] [b] (build-quantize-defs-recur (rest categories)
>> (rest boundaries)))
>> >
>> > Both functions work (on my example at least).
>> >
>> > One of the things I don't like, is my abusing (or the feeling that I am
>> abusing anyway) of this "into [] " idiom. I find myself constantly turning
>> things into vectors. That doesn't seem right and maybe I am using it in
>> places it's not needed. That's probably because I don't quite have a very
>> good idea of how collections work just yet.
>> >
>> > Thanks for any feedback.
>>
>  --
> 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
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
>

-- 
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
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: Function that "weaves" two collections together - looking for feedback

2014-02-18 Thread Laurent Droin
Ah, thank you. "interleave" is what I was looking for. I looked for 
"weave", "zip", "map", "concat", and all the "see also" but did not find 
"interleave".
Interleave will of course not handle the last value in the categories 
collection so my first instinct will be to call (into [] ) on the map 
returned by interleave, and to add (using conj) the (last categories) to 
the vector. Not sure whether there is a better way.

On Tuesday, February 18, 2014 9:17:54 PM UTC-8, Michael Gardner wrote:
>
> You may be interested in the core function 'interleave'. As for (into []), 
> it's perfectly idiomatic as long as you actually need to return a vector 
> and not just some kind of sequence (the more common case). But note also 
> the mapv/filterv/reduce-kv family of functions, though they're not directly 
> applicable here. 
>
> On Feb 18, 2014, at 22:58 , Laurent Droin > 
> wrote: 
>
> > Hi, 
> > 
> > Continuing my little pet project (small program really) to learn 
> Clojure, I am now working on a function whose description would be 
> something like: 
> >   "Returns a collection 'weaving' 2 collections (boundaries into 
> categories). 
> >   Boundaries must have one element less than categories. 
> >   For example, if categories is [:z1 :z2 :z3 :z4 :z5]   
> >   and boundaries is [120 150 165 180] 
> >   returns [:z1 120 :z2 150 :z3 165 :z4 180 :z5]" 
> > 
> > Assume the precondition is enforced. 
> > If categories has n elements, boundaries has n-1. 
> > 
> > I have tried to come up with a good implementation. I actually came up 
> with two, one that is non recursive, and one that is recursive. But I'm not 
> fully satisfied. I have the feeling that it's possible to make the function 
> simpler, and more elegant but I only know a subset of Clojure and am surely 
> missing some good idioms that I could/should be using. 
> > So once again, relying on feedback from experienced Clojurists to show 
> me the way :-) 
> > 
> > Here is what I have so far: 
> > 
> > 1- the non recursive function - based on mapcat 
> > (defn build-quantize-defs 
> > 
> >   
> > [categories boundaries] 
> > 
> > 
> > (conj (into [] (mapcat #(vector %1 %2) categories boundaries)) (last 
> categories))) 
> > 
> > 2 - the recursive function 
> > (defn build-quantize-defs-recur [categories boundaries] 
> > 
> >   
> > (let [c (first categories) b (first boundaries)] 
> > 
> > 
> > (if (nil? b) 
> >   
> >   
> > [c] 
> >   
> >   
> > (into [] (concat [c] [b] (build-quantize-defs-recur (rest categories) 
> (rest boundaries))) 
> > 
> > Both functions work (on my example at least). 
> > 
> > One of the things I don't like, is my abusing (or the feeling that I am 
> abusing anyway) of this "into [] " idiom. I find myself constantly turning 
> things into vectors. That doesn't seem right and maybe I am using it in 
> places it's not needed. That's probably because I don't quite have a very 
> good idea of how collections work just yet. 
> > 
> > Thanks for any feedback. 
>

-- 
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
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: Function that "weaves" two collections together - looking for feedback

2014-02-18 Thread Michael Gardner
You may be interested in the core function 'interleave'. As for (into []), it's 
perfectly idiomatic as long as you actually need to return a vector and not 
just some kind of sequence (the more common case). But note also the 
mapv/filterv/reduce-kv family of functions, though they're not directly 
applicable here.

On Feb 18, 2014, at 22:58 , Laurent Droin  wrote:

> Hi,
> 
> Continuing my little pet project (small program really) to learn Clojure, I 
> am now working on a function whose description would be something like:
>   "Returns a collection 'weaving' 2 collections (boundaries into categories).
>   Boundaries must have one element less than categories.
>   For example, if categories is [:z1 :z2 :z3 :z4 :z5]  
>   and boundaries is [120 150 165 180] 
>   returns [:z1 120 :z2 150 :z3 165 :z4 180 :z5]"
> 
> Assume the precondition is enforced.
> If categories has n elements, boundaries has n-1.
> 
> I have tried to come up with a good implementation. I actually came up with 
> two, one that is non recursive, and one that is recursive. But I'm not fully 
> satisfied. I have the feeling that it's possible to make the function 
> simpler, and more elegant but I only know a subset of Clojure and am surely 
> missing some good idioms that I could/should be using.
> So once again, relying on feedback from experienced Clojurists to show me the 
> way :-)
> 
> Here is what I have so far:
> 
> 1- the non recursive function - based on mapcat
> (defn build-quantize-defs
> 
>   
> [categories boundaries]
> 
> 
> (conj (into [] (mapcat #(vector %1 %2) categories boundaries)) (last 
> categories)))
> 
> 2 - the recursive function
> (defn build-quantize-defs-recur [categories boundaries]
> 
>   
> (let [c (first categories) b (first boundaries)]
> 
> 
> (if (nil? b)
>  
>   
> [c]
>  
>   
> (into [] (concat [c] [b] (build-quantize-defs-recur (rest categories) (rest 
> boundaries)))
> 
> Both functions work (on my example at least).
> 
> One of the things I don't like, is my abusing (or the feeling that I am 
> abusing anyway) of this "into [] " idiom. I find myself constantly turning 
> things into vectors. That doesn't seem right and maybe I am using it in 
> places it's not needed. That's probably because I don't quite have a very 
> good idea of how collections work just yet. 
> 
> Thanks for any feedback.

-- 
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
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.