Skip to content

Instantly share code, notes, and snippets.

@julien-f
Created November 17, 2022 17:28
Show Gist options
  • Save julien-f/f57a41ede947e85bd2ba516bedfba6fc to your computer and use it in GitHub Desktop.
Save julien-f/f57a41ede947e85bd2ba516bedfba6fc to your computer and use it in GitHub Desktop.
Simple JS create selector
const UNINITIALIZED = {}
export function createSelector() {
const nInputSelectors = arguments.length - 1
if (nInputSelectors <= 0) {
throw new Error('invalid number of inputs')
}
const transform = arguments[nInputSelectors]
if (nInputSelectors === 1) {
const inputSelector = arguments[0]
let prevInput = UNINITIALIZED
let prevResult
return function selector() {
const input = inputSelector.apply(this, arguments)
if (input !== prevInput) {
prevResult = transform.call(this, input)
prevInput = input
}
return prevResult
}
}
const inputSelectors = Array.prototype.slice(arguments, 0, nInputSelectors)
const prevInputs = Array.from({ length: nInputSelectors }, () => UNINITIALIZED)
let prevResult
return function selector() {
let inputsChanged = false
for (let i = 0; i < nInputSelectors; ++i) {
const input = inputSelectors[i].apply(this, arguments)
if (input !== prevInputs[i]) {
inputsChanged = true
prevInputs[i] = input
}
}
if (inputsChanged) {
prevResult = transform.apply(this, prevInputs)
}
return prevResult
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment