Skip to content
Vesa Karvonen edited this page Nov 9, 2017 · 17 revisions

This page contains a collection of 'recipes', simple examples of partial.lenses-based solutions to common problems.

In the examples on this page, L is partial.lenses and R is ramda.

Recipes

Isomorphic Conversion between an Array of Objects and a Single Object

Isomorphism (L.iso) that converts between a structure like this:

[ { id: 'a', val: 1 }, { id: 'b', val: 2 } ]

and one like this:

{ a: 1, b: 2 }

See it in action on the partial.lenses Playground

const data = [ { id: 'a', val: 1 }, { id: 'b', val: 2 } ]

const arrayToObjectL = ( keyProp, valProp ) => xs =>
  xs.reduce( ( acc, x ) => { acc[ x[ keyProp ] ] = x[ valProp ]; return acc }, {} )
const objectToArrayL = ( keyProp, valProp ) => obj =>
  Object.keys( obj ).map( x => ( { [ keyProp ]: x, [ valProp ]: obj[ x ] } ) )
const arrayToObjectIsoL = ( keyProp, valProp ) =>
  L.iso( arrayToObjectL( keyProp, valProp ), objectToArrayL( keyProp, valProp ) )

const d1 = L.get( arrayToObjectIsoL( 'id', 'val' ), data )
const d2 = L.modify( [ arrayToObjectIsoL( 'id', 'val' ), L.values ], R.inc, data )

R.identity( { d1, d2 } )

// result:
{ "d1": { "a": 1, "b": 2 },
  "d2": [ { "id": "a", "val": 2 }, { "id": "b" "val": 3 } ]
}

^ Back to Top

Convert JSON Pointer to Optic

This function converts a JSON Pointer in JSON String Representation format to a valid partial.lenses optic.

See it in action on the partial.lenses Playground: JSON Pointer

const pointer = s =>
  { const o = f => g => h => f(g(h))
    const isArray = x => !(x instanceof Object) || Array.isArray(x)
    return(
      o(xs =>
           1 === xs.length
             ? L.identity
             : o(ys =>
                    ys.map(x =>
                             /^([0-9]|[1-9][d]+)$/.test(x)
                               ? L.ifElse(isArray, Number(x), x)
                               : '-' === x
                               ? L.ifElse(isArray, L.append, x)
                               : o(y => y.replace('~0', '~'))
                                  (y => y.replace('~1', '/'))
                                  (x)
                          )
                )
                (x => x.slice(1))
                (xs)
       )
       (p => p.split('/'))
       (s)
    )  
  }

^ Back to Top