@@ -6,22 +6,24 @@ var _undefined
66function ObjectMapper ( from_object , to_object , property_map )
77{
88 global . elapsed [ 'ObjectMapper' ] . n ++ // performance monitoring
9+ let timer = performance . now ( )
910
1011 // There are a few different constructors - move around properties if needed
1112 if ( typeof property_map === 'undefined' ) {
12- property_map = to_object ;
13+ property_map = to_object
1314 to_object = _undefined
1415 }
1516
16- for ( const [ from_key , to_key ] of Object . entries ( property_map ) ) {
17+ // Loop through the map to process individual mapping instructions
18+ for ( const [ from_key_str , to_key_str ] of Object . entries ( property_map ) ) {
1719
18- // Traverse the 'from' object
19- var from_data = getKeyValue ( from_object , from_key )
20-
21- // Insert into the 'to' object
22- to_object = setKeyValue ( to_object , to_key , from_data )
20+ global . elapsed [ 'ObjectMapper' ] . ms += ( performance . now ( ) - timer )
21+ const from_data = getKeyValue ( from_object , from_key_str )
22+ to_object = setKeyValue ( to_object , to_key_str , from_data )
23+ timer = performance . now ( )
2324 }
2425
26+ global . elapsed [ 'ObjectMapper' ] . ms += ( performance . now ( ) - timer )
2527 return to_object
2628}
2729
@@ -30,11 +32,14 @@ function update(obj, data, key_arr)
3032{
3133 global . elapsed [ 'update' ] . n ++ // performance monitoring
3234 let timer = performance . now ( )
35+
3336 let x = 0 // index of the key array
3437
3538 var o
3639 // Get the object key and index that needs to be parsed
37- var [ key , ix ] = process ( key_arr . shift ( ) )
40+ global . elapsed [ 'update' ] . ms += ( performance . now ( ) - timer )
41+ var [ key , ix ] = key_arr . shift ( )
42+ timer = performance . now ( )
3843
3944 // If there is a key, we need to traverse down to this part of the object
4045 if ( key ) {
@@ -59,8 +64,10 @@ function update_obj(obj, key, data, key_arr)
5964 let timer = performance . now ( )
6065
6166 // If the object is undefined, we need to create a new object
62- if ( obj == null ) obj = { }
63- // Set the key of the object equal to the recursive, or if at the end, the data
67+ if ( obj == null )
68+ obj = { }
69+
70+ // Set the key of the object equal to the recursive, or if at the end, the data
6471 if ( key_arr . length > 0 ) {
6572 global . elapsed [ 'update_obj' ] . ms += ( performance . now ( ) - timer )
6673 obj [ key ] = update ( obj [ key ] , data , key_arr )
@@ -90,6 +97,7 @@ function update_arr(obj, key, ix, data, key_arr)
9097 return o
9198 }
9299 } , obj )
100+ global . elapsed [ 'update_arr' ] . ms += ( performance . now ( ) - timer )
93101 return obj
94102 }
95103 // If there is more work to be done, push an object onto the array
@@ -115,33 +123,23 @@ function select(obj, key_arr)
115123 global . elapsed [ 'select' ] . n ++ // performance monitoring
116124 let timer = performance . now ( )
117125
118- // Check to see if key_arr is not an array. If so, wrap it in an array.
119- // This is done for backwards compatibility from external functions that pass in a string
120- if ( ! Array . isArray ( key_arr ) )
121- key_arr = parse ( key_arr )
122-
123- // If we are at the end of the key array x`stack, return the object
124- if ( key_arr . length == 0 ) {
125- global . elapsed [ 'update_arr' ] . ms += ( performance . now ( ) - timer )
126- return obj
127- }
128-
129126 // Get the object key or index that needs to be parsed
130- global . elapsed [ 'update_arr ' ] . ms += ( performance . now ( ) - timer )
131- var [ key , ix ] = process ( key_arr . shift ( ) )
127+ global . elapsed [ 'select ' ] . ms += ( performance . now ( ) - timer )
128+ var [ key , ix ] = key_arr . shift ( )
132129 timer = performance . now ( )
133130
134131 // If there is an object key, grab the object property
135132 if ( key ) {
136- global . elapsed [ 'update_arr ' ] . ms += ( performance . now ( ) - timer )
133+ global . elapsed [ 'select ' ] . ms += ( performance . now ( ) - timer )
137134 return select_obj ( obj , key , key_arr )
138135 }
139136
140137 // If we need to deal with an array, then loop through and return recursive select for each
141138 if ( Array . isArray ( obj ) ) {
142- global . elapsed [ 'update_arr ' ] . ms += ( performance . now ( ) - timer )
139+ global . elapsed [ 'select ' ] . ms += ( performance . now ( ) - timer )
143140 return select_arr ( obj , key , ix , key_arr )
144141 }
142+ global . elapsed [ 'select' ] . ms += ( performance . now ( ) - timer )
145143}
146144
147145function select_obj ( obj , key , key_arr )
@@ -172,8 +170,9 @@ function select_arr(obj, key, ix, key_arr)
172170 // Recursively loop through the array and grab the data
173171 obj = obj . map ( function ( o ) {
174172 global . elapsed [ 'select_arr' ] . ms += ( performance . now ( ) - timer )
175- return select ( o , key_arr . slice ( ) )
173+ let _o = select ( o , key_arr . slice ( ) )
176174 timer = performance . now ( )
175+ return _o
177176 } )
178177 // obj = obj.map( function(o) {
179178 // global.elapsed['select_arr'].ms += (performance.now() - timer)
@@ -191,78 +190,96 @@ function select_arr(obj, key, ix, key_arr)
191190
192191// Turns a key string (like key1.key2[].key3 into ['key1','key2','[]','key3']...)
193192//
194- function parse ( key , delimiter = '.' )
193+ function parse ( key_str , delimiter = '.' )
195194{
196195 global . elapsed [ 'parse' ] . n ++ // performance monitoring
197196 let timer = performance . now ( )
198-
199- if ( typeof ( key ) == 'string' ) {
200- var key_array = key . split ( delimiter )
201- var keys = key_array . reduce ( function ( keys , current_key ) {
202- var [ k , ix ] = process ( current_key )
203- if ( k ) keys . push ( k )
204- if ( ix !== null ) keys . push ( '[' + ix + ']' )
205- return keys
206- } , [ ] )
207- global . elapsed [ 'parse' ] . ms += ( performance . now ( ) - timer )
208- return keys
197+ let _default = null
198+ let _transpose = null
199+
200+ // If the value was passed in object notation, grab the default and transpose values, then rewrite as a string
201+ if ( typeof ( key ) == 'object' ) {
202+ _default = key_str . default
203+ _transpose = key_str . transpose
204+ key_str = key_str . key
209205 }
210- global . elapsed [ 'parse' ] . ms += ( performance . now ( ) - timer )
211- }
212-
213- function process ( k )
214- {
215- global . elapsed [ 'process' ] . n ++ // performance monitoring
216- let timer = performance . now ( )
217206
218- var arr
219- try {
220- var [ _ , key , ix ] = k . match ( / ( .* ?) \[ ( .* ?) \] / )
221- arr = [ key , ix ]
222- } catch ( e ) {
223- arr = [ k , null ]
207+ const key_arr = key_str . split ( delimiter )
208+ let keys = [ ]
209+ let n = 0
210+ for ( let i = 0 , len1 = key_arr . length ; i < len1 ; i ++ ) {
211+ // Build a object which is either an object key or an array
212+ // Note that this is not the most readable, but it is fastest way to parse the string (at this point in time)
213+ let begin = - 1 , end = - 1 , key = key_arr [ i ]
214+ for ( let j = 0 , len2 = key . length ; j < len2 ; j ++ ) {
215+ if ( key [ j ] == '[' ) begin = j
216+ if ( key [ j ] == ']' && begin > - 1 ) {
217+ end = j
218+ break
219+ }
220+ }
221+ // No array - just add object key
222+ if ( begin == - 1 ) {
223+ keys [ n ++ ] = [ key_arr [ i ] || null , null ]
224+ }
225+ // No key - just add array index
226+ else if ( begin == 0 && end > 0 ) {
227+ keys [ n ++ ] = [ null , key_arr [ i ] . substring ( begin + 1 , end ) ]
228+ }
229+ // Both object and array key
230+ else if ( begin > 0 && end > 0 ) {
231+ keys [ n ++ ] = [ key . substring ( 0 , begin ) , null ]
232+ keys [ n ++ ] = [ null , key . substring ( begin + 1 , end ) ]
233+ }
224234 }
225235 global . elapsed [ 'parse' ] . ms += ( performance . now ( ) - timer )
226- return arr
227- }
236+ return keys
237+ }
228238
229239// A string of how to navigate through the incoming array is sent.
230240// This is translated into an array of instructions for the recursive object
231241function getKeyValue ( obj , key_str )
232242{
233243 global . elapsed [ 'getKeyValue' ] . n ++ // performance monitoring
244+ let timer = performance . now ( )
234245
235- // String
236- if ( typeof ( key_str ) == 'string' ) return select ( obj , parse ( key_str ) )
237- // Nothing else is valid
246+ // Convert the mapping string into an array of instructions
247+ // e.g. 'foo.bar[].baz => foo, bar, [], baz
248+ global . elapsed [ 'getKeyValue' ] . ms += ( performance . now ( ) - timer )
249+ let key_arr = parse ( key_str )
250+ timer = performance . now ( )
251+
252+ // Return the selected object
253+ global . elapsed [ 'getKeyValue' ] . ms += ( performance . now ( ) - timer )
254+ return select ( obj , key_arr )
238255}
239256
240- function setKeyValue ( obj , key_str , data )
257+ function setKeyValue ( obj , key_str , data )
241258{
242259 global . elapsed [ 'setKeyValue' ] . n ++ // performance monitoring
243-
244- // Key_str is written as a simple string
245- if ( typeof ( key_str ) == 'string' )
246- return update ( obj , data , parse ( key_str ) )
260+ let timer = performance . now ( )
247261
248262 // Key_str is an array of values
249263 if ( Array . isArray ( key_str ) ) {
250- for ( var i = 0 , len = key_str . length ; i < len ; i ++ ) {
251- obj = update ( obj , data , parse ( key_str [ i ] ) )
264+ for ( let i = 0 , len = key_str . length ; i < len ; i ++ ) {
265+ global . elapsed [ 'setKeyValue' ] . ms += ( performance . now ( ) - timer )
266+ let key_arr = parse ( to_key_str [ i ] )
267+ obj = update ( obj , data , key_arr )
268+ timer = performance . now ( )
252269 }
253- return obj
270+ } else {
271+ global . elapsed [ 'setKeyValue' ] . ms += ( performance . now ( ) - timer )
272+ let key_arr = parse ( key_str )
273+ obj = update ( obj , data , key_arr )
274+ timer = performance . now ( )
254275 }
255-
256- // Key_str is written in object notation form
257- if ( typeof ( key_str ) == 'object' )
258- return update ( obj , data , parse ( key_str . key ) )
259-
276+ global . elapsed [ 'setKeyValue' ] . ms += ( performance . now ( ) - timer )
277+ return obj
260278 // Nothing else is valid
261279}
262280
263281module . exports = ObjectMapper
264282module . exports . getKeyValue = getKeyValue
265283module . exports . setKeyValue = setKeyValue
266- module . exports . process = process
267284module . exports . parse = parse
268285// module.exports.merge = ObjectMapper;
0 commit comments