lib/index.js
/*
	* params: options.obj, options.currentLocation

	* options.obj: obj is object you are flattening. When calling this function, you only need to provide obj as an argument. 
	* options.loc: Only used when the function recurses for maintaining the current path.

	* Uses the orderIndependentCollections object to determine what keys to use
	* to flatten arrays into objects. Arrays are transformed into objects by creating
	* objects out of their existing array elements, attaching those elements to their parent, and 
	* uniquely identifying them by a field with a unique value inside the element 
	* which is defined in orderIndependentCollections. 

	* A side effect of flattening is that dates will be stringified in this step in order to do a patch comparison with the output that does not result in
	* a malformed patch.

	 	Ex:

	   collection: [{
        collectionId: 'xxx-yyy-zzz'
      }]

     becomes

     collection: {
        'xxx-yyy-zzz': {
          collectionId: 'xxx-yyy-zzz'
        }
      }

  * Returns a flattened object.
	*/


Uses the orderIndependentCollections object to determine what keys to use
to flatten arrays into objects. Arrays are transformed into objects by creating
objects out of their existing array elements, attaching those elements to their parent, and
uniquely identifying them by a field with a unique value inside the element
which is defined in orderIndependentCollections.

A side effect of flattening is that dates will be stringified in this step in order to do a patch comparison with the output that does not result in
a malformed patch.



[{
collectionId: 'xxx-yyy-zzz'
}]

becomes

{
'xxx-yyy-zzz': {
collectionId: 'xxx-yyy-zzz'
}
}

Returns a flattened object.
Uses the orderIndependentCollections object to determine what keys to use to flatten arrays into objects . Arrays are transformed into objects by creating objects out of their existing array elements attaching those elements to their parent and uniquely identifying them by a field with a unique value inside the element which is defined in orderIndependentCollections . A side effect of flattening is that dates will be stringified in this step in order to do a patch comparison with the output that does not result in a malformed patch . [ { collectionId : ' xxx - yyy - zzz ' } ] becomes { ' xxx - yyy - zzz ' : { collectionId : ' xxx - yyy - zzz ' } } Returns a flattened object .
flatten(options) {
		var obj = options.obj
		var currentLocation = options.currentLocation
		if (Array.isArray(obj)) {
		  var collectionOptions = this.options.orderIndependentCollections[currentLocation]
		  if(collectionOptions && collectionOptions.key) {
		    obj = obj.reduce((memo, item) => {
		    	var key = moment.isDate(item[collectionOptions.key]) ? moment(item[collectionOptions.key]).toISOString() : `${item[collectionOptions.key]}`
		      memo[key] = this.flatten({
		      	obj: item,
		      	currentLocation: currentLocation
		      })
		      return memo
		    }, {})
		  }
		  else {
		    obj = obj.map(o => {
		      return this.flatten({
		      	obj: o, 
		      	currentLocation: currentLocation
		      })
		    })
		  }
		}
		else if (typeof obj === 'object' && obj !== null) {
		  Object.keys(obj).forEach(k => {
		    obj[k] = this.flatten({
		    	obj: moment.isDate(obj[k]) ? moment(obj[k]).toISOString() : obj[k], 
		    	currentLocation: `${currentLocation ? currentLocation + '.' : ''}${k}`})
		  })
		} 
		return obj
	}
flatten ( options ) { var obj = options . obj var currentLocation = options . currentLocation if ( Array . isArray ( obj ) ) { var collectionOptions = this . options . orderIndependentCollections [ currentLocation ] if ( collectionOptions && collectionOptions . key ) { obj = obj . reduce ( ( memo , item ) => { var key = moment . isDate ( item [ collectionOptions . key ] ) ? moment ( item [ collectionOptions . key ] ) . toISOString ( ) : ` ${ item [ collectionOptions . key ] } ` memo [ key ] = this . flatten ( { obj : item , currentLocation : currentLocation } ) return memo } , { } ) } else { obj = obj . map ( o => { return this . flatten ( { obj : o , currentLocation : currentLocation } ) } ) } } else if ( typeof obj === 'object' && obj !== null ) { Object . keys ( obj ) . forEach ( k => { obj [ k ] = this . flatten ( { obj : moment . isDate ( obj [ k ] ) ? moment ( obj [ k ] ) . toISOString ( ) : obj [ k ] , currentLocation : ` ${ currentLocation ? currentLocation + '.' : '' } ${ k } ` } ) } ) } return obj }
params: options.obj, options.currentLocation
 options.obj: obj is object you are flattening.
params : options . obj options . currentLocation options . obj : obj is object you are flattening .