const { lens, find, has, findIndex, assocPath, update,
append, assoc, view, set, over, inc} = R
const pageAttrValueLens = (pageName, attrName) => lens(
(pages) => (find(
has(attrName),
(pages[pageName] || {attrs: []}).attrs
) || {[attrName]: {value: 0}})[attrName].value,
(val, pages) => {
const page = pages[pageName] || {attrs: []}
const attrIdx = findIndex(has(attrName), page.attrs)
const idx = attrIdx === -1 ? page.attrs.length : attrIdx
const attr = page.attrs[idx] || {[attrName]: {value: 0}}
const newAttr = assocPath([attrName, 'value'], val, attr)
const attrs = idx < page.attrs.length
? update(idx, newAttr, page.attrs)
: append(newAttr, page.attrs)
const newPage = assoc('attrs', attrs, page)
return assoc(pageName, newPage, pages)
}
)
const pages = {
'page1': {
'attrs': [
{'attr1': {'value': 10}},
{'attr2': {'value': 20}}
]
}
}
console.log(view(pageAttrValueLens('page1', 'attr2'), pages)) //=> 20
console.log(view(pageAttrValueLens('page1', 'attr3'), pages)) //=> 0
console.log(view(pageAttrValueLens('page2', 'attr1'), pages)) //=> 0
console.log(set(pageAttrValueLens('page1', 'attr2'), 42, pages))
//=> {"page1":{"attrs":[{"attr1":{"value":10}},{"attr2":{"value":42}}]}}
console.log(set(pageAttrValueLens('page1', 'attr3'), 42, pages))
//=> {"page1":{"attrs":[{"attr1":{"value":10}},{"attr2":{"value":20}},{"attr3":{"value":42}}]}}
console.log(set(pageAttrValueLens('page2', 'attr1'), 42, pages))
//=> {"page1":{"attrs":[{"attr1":{"value":10}},{"attr2":{"value":20}}]},"page2":{"attrs":[{"attr1":{"value":42}}]}}
console.log(over(pageAttrValueLens('page1', 'attr2'), inc, pages))
//=> {"page1":{"attrs":[{"attr1":{"value":10}},{"attr2":{"value":21}}]}}
console.log(over(pageAttrValueLens('page1', 'attr3'), inc, pages))
//=> {"page1":{"attrs":[{"attr1":{"value":10}},{"attr2":{"value":20}},{"attr3":{"value":1}}]}}
console.log(over(pageAttrValueLens('page2', 'attr1'), inc, pages))
//=> {"page1":{"attrs":[{"attr1":{"value":10}},{"attr2":{"value":20}}]},"page2":{"attrs":[{"attr1":{"value":1}}]}}
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js"></script>