Skip to main content
Code Review

Return to Answer

replaced http://stackoverflow.com/ with https://stackoverflow.com/
Source Link

All these solutions are assuming that it is fine to re-enumerate the sequence, i.e. by truncating once and then skipping. That might be an OK assumption for small, in-memory data-sets, but an IEnumerable doesn't have to allow multiple enumeration, and it can be expensive. As pointed out pointed out by Tomas Petricek on that other question, due to the forward-only nature of sequences, whenever you "back up" over a sequence like this it actually has to enumerate the entire thing from the beginning.

All these solutions are assuming that it is fine to re-enumerate the sequence, i.e. by truncating once and then skipping. That might be an OK assumption for small, in-memory data-sets, but an IEnumerable doesn't have to allow multiple enumeration, and it can be expensive. As pointed out by Tomas Petricek on that other question, due to the forward-only nature of sequences, whenever you "back up" over a sequence like this it actually has to enumerate the entire thing from the beginning.

All these solutions are assuming that it is fine to re-enumerate the sequence, i.e. by truncating once and then skipping. That might be an OK assumption for small, in-memory data-sets, but an IEnumerable doesn't have to allow multiple enumeration, and it can be expensive. As pointed out by Tomas Petricek on that other question, due to the forward-only nature of sequences, whenever you "back up" over a sequence like this it actually has to enumerate the entire thing from the beginning.

deleted 10 characters in body
Source Link
luksan
  • 256
  • 1
  • 3

Seq.foldunfold Solution

let segmented (size:int) (source:'t[]) =
 let maxPos = source.Length - 1
 [| for pos in 0 .. size .. maxPos ->
 source.[pos .. min (pos + size - 1) maxPos] |]

Seq.fold Solution

let segmented (size:int) (source:'t[]) =
 let maxPos = source.Length - 1
 [| for pos in 0 .. size .. maxPos ->
 source.[pos .. min (pos + size - 1) maxPos] |]

Seq.unfold Solution

let segmented (size:int) (source:'t[]) =
 let maxPos = source.Length - 1
 [| for pos in 0 .. size .. maxPos ->
 source.[pos .. min (pos + size - 1) maxPos] |]
deleted 77 characters in body
Source Link
luksan
  • 256
  • 1
  • 3

Mutability is somewhat frowned upon in functional languagesFunctional-first style tends to prefer immutability over mutability, so the fact that you're using ref signifiescan sometimes signify that the code could be more idiomatic.

But perhaps a sequence isn't the best choice of data types for input into this function. If the data is already in memory, you have a choice of turning it into a list or an array. Arrays are especially nice for this problem due to their support for slicing. Here's a solution that uses an array for sourcearrays instead of sequences:

let rec chop segmentSize source =
 segmented if(size:int) (source:'t[]) = [||] then Seq.empty else
 let lenmaxPos = Arraysource.lengthLength source- |>1
 min segmentSize
 [| for letpos segmentin =0 source.[. size .. lenmaxPos - 1]>
 let rest = source.[len[pos ..]
 min (pos + Seq.appendsize [Seq.ofArray- segment]1) (chopmaxPos] segmentSize rest) |]

Mutability is somewhat frowned upon in functional languages, so the fact that you're using ref signifies that the code could be more idiomatic.

But perhaps a sequence isn't the best choice of data types for input into this function. If the data is already in memory, you have a choice of turning it into a list or an array. Arrays are especially nice for this problem due to their support for slicing. Here's a solution that uses an array for source:

let rec chop segmentSize source =
  if source = [||] then Seq.empty else
 let len = Array.length source |> min segmentSize
 let segment = source.[.. len - 1]
 let rest = source.[len ..]
 Seq.append [Seq.ofArray segment] (chop segmentSize rest)

Functional-first style tends to prefer immutability over mutability, so the fact that you're using ref can sometimes signify that the code could be more idiomatic.

But perhaps a sequence isn't the best choice of data types for input into this function. If the data is already in memory, you have a choice of turning it into a list or an array. Arrays are especially nice for this problem due to their support for slicing. Here's a solution that uses arrays instead of sequences:

let segmented (size:int) (source:'t[]) =
 let maxPos = source.Length - 1
 [| for pos in 0 .. size .. maxPos ->
 source.[pos .. min (pos + size - 1) maxPos]  |]
added 51 characters in body
Source Link
luksan
  • 256
  • 1
  • 3
Loading
added 256 characters in body
Source Link
luksan
  • 256
  • 1
  • 3
Loading
added 895 characters in body
Source Link
luksan
  • 256
  • 1
  • 3
Loading
added 4 characters in body
Source Link
luksan
  • 256
  • 1
  • 3
Loading
Source Link
luksan
  • 256
  • 1
  • 3
Loading
lang-ml

AltStyle によって変換されたページ (->オリジナル) /