Skip to content

Instantly share code, notes, and snippets.

@milankinen
Created March 2, 2016 21:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save milankinen/a6aa2e6525c04369a4c7 to your computer and use it in GitHub Desktop.
Save milankinen/a6aa2e6525c04369a4c7 to your computer and use it in GitHub Desktop.
import R from "ramda"
const subLens = (by, val, def) => {
const orDefault = val => val === undefined ? def : val
const matches = R.compose(R.equals(val), by)
return R.lens(
s => orDefault(R.find(matches, s)),
(a, s) => {
const idx = R.findIndex(matches, s)
return idx >= 0 ? R.set(R.lensIndex(idx), a, s) : s
})
}
// liftListBy :: (s -> a) -> Atom [{a,b}] -> (a -> Atom b -> Atom c) -> Atom [Atom(c)]
export const liftListBy = R.curry((by, listAtom, subModel, defaultValue = {}) =>
listAtom
.scan((cache, m) => {
const itemsByKey = R.indexBy(by, m)
const added = m.map(by).filter(key => !(key in cache)).map(key =>
subModel(key, listAtom.lens(subLens(by, key, defaultValue))))
const removed =
R.keys(cache).filter(key => !(key in itemsByKey))
return R.isEmpty(added) && R.isEmpty(removed) ? cache : R.pipe(
R.merge(R.indexBy(by, added)),
R.omit(removed)
)(cache)
}, {})
.skipDuplicates()
.map(R.values)
.toProperty())
export const liftListById = liftListBy(R.prop("id"))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment