All Projects â†’ mfix22 â†’ morphmorph

mfix22 / morphmorph

Licence: MIT license
😱 Isomorphic transformations. Map, transform, filter, and morph your objects

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to morphmorph

stream
Go Stream, like Java 8 Stream.
Stars: ✭ 60 (+130.77%)
Mutual labels:  functional, filter, reduce
linq
A familiar set of functions that operate on JavaScript iterables (ES2015+) in a similar way to .NET's LINQ does with enumerables.
Stars: ✭ 39 (+50%)
Mutual labels:  filter, reduce
dry-transformer
Data transformation toolkit
Stars: ✭ 59 (+126.92%)
Mutual labels:  functional, function-composition
Bull
BULL - Bean Utils Light Library
Stars: ✭ 150 (+476.92%)
Mutual labels:  mapping, transformations
grand central
State-management and action-dispatching for Ruby apps
Stars: ✭ 20 (-23.08%)
Mutual labels:  functional, isomorphic
Fungen
Replace boilerplate code with functional patterns using 'go generate'
Stars: ✭ 122 (+369.23%)
Mutual labels:  functional, filter
Fabulousfilter
Android library to animate Floating Action Button to Bottom Sheet Dialog and vice-versa
Stars: ✭ 2,477 (+9426.92%)
Mutual labels:  filter, morph
Hm
Idiomatic Ruby hash transformations
Stars: ✭ 121 (+365.38%)
Mutual labels:  functional, transformations
Elements-of-Functional-Programming-in-Python
Learn how to how to use the lambda, map, filter and reduce functions in Python to transform data structures.
Stars: ✭ 14 (-46.15%)
Mutual labels:  filter, reduce
PartialFunctions.jl
A small package to simplify partial function application
Stars: ✭ 34 (+30.77%)
Mutual labels:  functional, function-composition
python-graphslam
Graph SLAM solver in Python
Stars: ✭ 118 (+353.85%)
Mutual labels:  mapping
Mappable
flexible JSON to Model converter, specially optimized for immutable properties
Stars: ✭ 27 (+3.85%)
Mutual labels:  mapping
hacker-rank
Functional Path do hacker Rank
Stars: ✭ 48 (+84.62%)
Mutual labels:  functional
react-ssr-hydration
Example of React Server Side Rendering with Styled Components and Client Side Hydration
Stars: ✭ 15 (-42.31%)
Mutual labels:  isomorphic
dissect-tester
Simple API/UI for testing filebeat dissect patterns against a collection of sample log lines.
Stars: ✭ 58 (+123.08%)
Mutual labels:  filter
nova-inline-morph-to
A Laravel Nova field for displaying morphTo relationship inline.
Stars: ✭ 32 (+23.08%)
Mutual labels:  morph
DrupalTwigFood
Useful functions, filters for twig @ Drupal 8
Stars: ✭ 1 (-96.15%)
Mutual labels:  filter
geologic-symbols-qgis
Geologic symbols library and development for QGIS
Stars: ✭ 63 (+142.31%)
Mutual labels:  mapping
fastify-vite
This plugin lets you load a Vite client application and set it up for Server-Side Rendering (SSR) with Fastify.
Stars: ✭ 497 (+1811.54%)
Mutual labels:  isomorphic
demo-oracle-mybatis
No description or website provided.
Stars: ✭ 26 (+0%)
Mutual labels:  mapping

Morph Morph

Isomorphic transformations. Map, transform, filter, reduce, and morph your objects

tested with jest linted with XO styled with prettier

Getting Started

$ npm i --save morphmorph

and then

const Mapper = require('morphmorph')

const mapper = new Mapper(/* [config] */)

const old = {
  here: {
    there: {
      anywhere: 'Earth'
    }
  }
}

const mappings = [ 'here.there.anywhere:location' ]

const transformation = mapper.map(mappings, old)
// -> { location: 'Earth' }

Creating Transformations

Every transformation can be represented by a mapping passed in as the first parameter to mapper.map(). Mappings can either be of type String or Object. A mapping such as 'before:after' is equivalent to: { field: 'before:after' }

Basic

const mappings = [
  'before:after',
  'egg:they.can.be.deeply.nested', // deeply nested target
  'data.user.updated:updated'      // deeply nested source
]
return mapper.map(mappings, obj)

Functions

When creating a mapping, if you pass a function as the type parameter, the function you passed will be called with the following properties to produce the result:

const mapping = {
  field: 'name',
  type: function (value, mapping, options, sourceObj, targetObj) {
    // value: the value grabbed from the source object
    // mapping: this specific mapping
    // options: config you specified by `new Mapper(options)`
    // sourceObj: object you passed as mapper.map(mapping, sourceObj)
    // targetObj: object you passed as mapper.map(m, sourceObj, targetObj). Default to `{}`
  }
}

Arrays

You can also pass an Array of functions and MapLib will perform a right-to-left function composition:

const mapping = {
  field: 'id:pin',
  type: [
    Number,                   // called last
    v => v.substr(0, 4)
    v => v.replace(/\D/g, '') // called first
  ]
}

mapper.map([mapping], { id: 'U1234342'}) // -> 1234

Function Compositions

If you want to do function compositions the traditional way, you can use Mapper.compose(...myFilterFunctions). Again it will be a right-to-left composition.

Reductions

By specifying your field property as an array, you can reduce multiple values into a single one. The values will be included as the first parameter of your type function. The target field is specified by the last mapping in your array

Example
const response = {
  user: {
    firstName: 'Mike',
    lastName: 'Fix',
    professionInfo: {
      title: 'Mr',
      occupation: 'Software Engineer'
    }
  }
}

const mapping = {
  field: [
    'user.firstName',
    'user.lastName',
    'user.professionInfo.title',
    'user.professionInfo.occupation',
    'description'
  ],
  type: ([name1, name2, title, occ]) =>
    `${title}. ${name1} ${name2} is a ${occ}`
}

mapper.map([mapping], response).description // -> 'Mr. Mike Fix is a Software Engineer'

Types

You can specify a type system by passing in the types option:

const types = {
  number: Number,
  notNullString: v => (v || '')
}

const mapper = new Mapper({ types })

and then specify which type to use as a string for each mapping:

const mappings = [
  { field: 'haircolor', type: 'notNullString' },
  { field: 'daysRemaining': type: 'number' }
]

return mapper.map(mappings, hairSubscriptionResponse)

Note: each function in the type specification is passed the same parameters as the normal type functions

Config

You can pass in a config object to Mapper to create your own mapping system:

Options
Field Type Default
types Object {}
objDelimiter String "."
mapDelimiter String ":"
preFilters Array []
postFilters Array []
Example
const mapper = new Mapper({
  objDelimiter: '|',
  mapDelimiter: '->',
  types: { bool: Boolean },
  preFilters: [ FILTER_NULL ],
  postFilters: [ REMOVE_PASSWORD ]
  // add other fields to your config here
})

Static methods

Mapper.get

Method used to grab a deeply nested field from an object.

const get = Mapper.get('key'/*, delimiter */)
const field = get({ key: true })
// -> true
Mapper.assign

Method used to apply a deeply nested field to an object.

const set = Mapper.assign('user.id'/*, delimiter */)
const targetObject = set({}, 1)
// -> { user: { id: 1 } }
Mapper.compose

Method used to apply function compositions

const fun1 = v => `${v}!`
const fun2 = v => v.toUpperCase()
const fun3 = String

const exclaim = Mapper.compose(fun1, fun2, fun3)
exclaim('hey') // -> HEY!

Bonus

Dependencies: None!
Size: <2KB gzipped

Examples

See /examples or test/index.spec.js for many examples of how to use MorphMorph.

Thanks

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].