open System
open System.Collections.Generic
open System.Linq
//splitEvery :: Int -> [a] -> [[a]]
let splitAt n (xs:IEnumerable<'a>) = (xs.Take n, xs.Skip n)
let rec splitEvery n xs =
let (ks, vs) = splitAt n xs in
seq { yield ks
yield! splitEvery n vs }
6 comments:
This seems rather inefficient, since you are enumerating over the enumerable twice for every split. The further you get into the enumerable the worse things are (imagine a 10000 element enumerable split every 10, on the 1000th split you are skipping 9990 elements to get the last 10).
This is the version I use (which, itself, could probably stand some improvement): http://gist.github.com/330586
I agree with you. I like the simplicity of it thought. I will provide a more efficient SplitAt (as soon as I get the time), one that doesn't enumerate twice. Thank you for your comment.
I have written almost same code too, see my function cut:
http://stackoverflow.com/questions/2649161/need-help-regarding-async-and-fsi
But your function slipEvery do not terminate, I think you should add a test like:
if (vs.Count() <> 0) then yield! splitEvery n vs
I have written a more efficient solution, yet still readable:
http://gist.github.com/453478
But it's cheating if you use mutable types. :)
“If you know how to cheat, start now.” ;) (quoting a famous Baltimore's baseball player)
Post a Comment