Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

F#: partition function like the one in Clojure

Tags:

clojure

f#

Clojure has a nice function called partition which works on sequences. It breaks a given sequence into a sequence of equally long lists. The first parameter specifies the length of the fragaments. The second parameter is an offset which specifies the next start of an fragment.

(partition 3 1 (range 5))
;;=> ((0 1 2) (1 2 3) (2 3 4))

(partition 4 6 (range 20))
;;=> ((0 1 2 3) (6 7 8 9) (12 13 14 15))

(partition 4 3 (range 20))
;;=> ((0 1 2 3) (3 4 5 6) (6 7 8 9) (9 10 11 12) (12 13 14 15) (15 16 17 18))

https://clojuredocs.org/clojure.core/partition

I'm looking for an equivalent function in F#. Clearly List.partition does something else (https://msdn.microsoft.com/en-us/library/ee353782.aspx). Maybe there is a library which offers such a function?

like image 645
Olaf Avatar asked Jan 07 '23 17:01

Olaf


1 Answers

In F# you have two similar functions: windowed which is like Clojure's partition but with second parameter fixed as 1 and chunkBySize with second parameter equals to the first.

You can combine both and get the desired function. Here's an example with Lists:

let partition x y = List.windowed x >> List.chunkBySize y >> List.map List.head

They're also available for arrays and sequences but note that for sequences the inner collection will be an array, which is actually a sequence. So if you want the result inferred strictly as a sequence of sequences you will have to add a conversion or upcast:

let partition x y = Seq.windowed x >> Seq.chunkBySize y >> Seq.map (Seq.head >> seq)
like image 103
Gus Avatar answered Jan 11 '23 07:01

Gus