gcanti / fp-ts

Functional programming in TypeScript
https://gcanti.github.io/fp-ts/
MIT License
10.82k stars 502 forks source link

Add `sliding` #1149

Open vicrac opened 4 years ago

vicrac commented 4 years ago

🚀 Feature request

I wonder if it's desirable to add sliding over Array, similar to List.sliding in Scala, or partition from Clojure:

// sliding(window, offset)
sliding(2, 1)([1, 2, 3]) ===
  [
    [1, 2],
    [2, 3]
  ]
sliding(2, 2)([1, 2, 3, 4]) ===
  [
    [1, 2],
    [3, 4]
  ]
sliding(1, 2)([1, 2, 3]) === [[1], [3]]

It makes easy e.g. checking whether all elements are equal:

sliding(2, 1)([1, 1, 1, 1]).every(([a1, a2]) => a1 === a2) === true

or calculating moving average:

sliding(3, 1)([1, 2, 3, 4, 5]).map(avg) === [2, 4, 5]

Suggested Solution

export function sliding(window: number, offset: number): <A>(xs: ReadonlyArray<A>) => ReadonlyArray<ReadonlyArray<A>> {
  return xs => (xs.length < window ? [] : [xs.slice(0, window), ...sliding(window, offset)(xs.slice(offset))])
}

Your environment

Software Version(s)
fp-ts 2.5
TypeScript 3.7.3
gcanti commented 4 years ago

Looks like is named divvy in this Haskell package