gen icon indicating copy to clipboard operation
gen copied to clipboard

skipping

Open nilsbecker opened this issue 5 years ago • 6 comments

i have not found a way to take only every nth element -- is this possible? have i missed it? more generally, one could think of a list of 'step lengths' or 'skip lengths' to apply cyclically as one moves over the generator, i.e. [0;2;1] means 'take next element, then skip two and take one, then skip one and take one, then take the next element, etc.,..'

nilsbecker avatar May 29 '19 12:05 nilsbecker

right now i am using chunks together with Array.get which seems not ideal.

nilsbecker avatar May 29 '19 14:05 nilsbecker

I think skip would be useful (it's pretty simple to write I think, with a tiny state machine). The more general version makes me more dubious, it seems hard to explain and rarely useful. Skip could look like:


let skip n gen =
  let i = ref n in
  let rec next() =
    match gen() with
    | None -> None
    | Some x when !i = 1 ->
      i := n; Some x
    | Some _ ->
      decr i; next()
  in next

c-cube avatar May 29 '19 14:05 c-cube

i would agree that the simple one is probably enough in >90% of the cases. the more general one just occurred to me by imagining a scenario like "i need successive pairs which occur every 7 elements" or something like that. however, then one could probably just use chunks and pay for array construction. another way of implementing general skipping would be to zip together two generators; one for the jump lengths and another one for the value stream. again, probably not widely useful.

nilsbecker avatar May 29 '19 15:05 nilsbecker

about naming: skip 4 to me means that every 5th element should be taken. so one has to be careful; maybe skip is not a good name, despite its ubiquity

nilsbecker avatar May 29 '19 15:05 nilsbecker

take_every ~nth:5 ?

c-cube avatar May 30 '19 18:05 c-cube

that's very clear i find. one could argue that take_every 5 is already enough but i guess that's taste

nilsbecker avatar Jun 03 '19 08:06 nilsbecker