Skip to content

Commit

Permalink
fixed for bug outlined in wankdanker#58
Browse files Browse the repository at this point in the history
  • Loading branch information
Scott Switzer committed Oct 6, 2019
1 parent bb1ad50 commit 2c2147b
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 90 deletions.
78 changes: 35 additions & 43 deletions src/object-mapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,16 @@ function ObjectMapper(from_object, to_object, property_map)
property_map = to_object;
to_object = _undefined
}
if (typeof to_object === 'undefined')
to_object = {}

var property_keys = Object.keys(property_map);
return map(from_object, to_object, property_map, property_keys)
return map(from_object, to_object, property_map)
}

function map(from_object, to_object, property_map, property_keys)
function map(from_object, to_object, property_map)
{
// loop through the property map key array, and place the contents in the from Object into the to Object
if (property_keys.length > 0) {
for (var i=0; i< property_keys.length; i++) {
var k = property_keys[i]
var from_key_arr = parse(k)
var from_data = select(from_object, from_key_arr)
// if we successfully extracted data, then place it into the new object
if (from_data != null) {
var to_key_arr = parse(property_map[k])
to_object = update(from_data, to_object, to_key_arr)
}
}
for (const [from_key, to_key] of Object.entries(property_map)) {
var from_data = select(from_object, from_key)
to_object = update(to_object, to_key, from_data)
}

return to_object
}

Expand All @@ -50,8 +37,8 @@ function update(obj, key_arr, data)
if (!Array.isArray(key_arr))
key_arr = parse(key_arr)

// If we are at the end of the key array stack, return the leaf data either as an object property or in an array
if (key_arr.length == 0) return Array.isArray(obj) ? [data] : data
// // If we are at the end of the key array stack, return the leaf data either as an object property or in an array
// if (key_arr.length == 0) return Array.isArray(obj) ? [data] : data

// Get the object key and index that needs to be parsed
var [key, ix] = process(key_arr.shift())
Expand All @@ -60,31 +47,29 @@ function update(obj, key_arr, data)
if (key) {
// If the object is undefined, we need to create a new object
if (obj == null) obj = {}
// Either grab the child key if it is defined, or create a new array or index
var o = obj.hasOwnProperty(key) ? obj[key] : (ix == null ? {} : [])
// Update the object with downstream data and keys
o = update(o, key_arr, data)
// either add the subobject onto an array...
if (Array.isArray(obj))
obj.push({[key]: o})
// ...or add as a key to the object
else obj[key] = o
// Set the key of the object equal to the recursive, or if at the end, the data
obj[key] = (key_arr.length > 0) ? update(obj[key], key_arr, data) : data
// return the newly created object to the top
return obj
}

if (ix !== null) {
// If the top level object is undefined, we need to create a new array
if (obj == null) obj = []
// If ix is specified, make sure that it is present
if (ix && !obj[ix]) obj[ix] = null
// Make sure that if the data element is a string that we put it into an array
if (typeof(data) == 'string') data = build_array(data, ix)
// Make sure that there is an array item for each item in the data array
obj = data.reduce(function(o,d,i) {
o[i] = update(o[i], key_arr.slice(), d)
return o
}, obj)
if (Array.isArray(data)) {
obj = data.reduce(function(o,d,i) {
if (i == '' || i == i)
o[i] = update(o[i], key_arr.slice(), d)
return o
}, obj)
return obj
}
// If there is more work to be done, push an object onto the array
else {
var x = (ix) ? ix : 0
obj[x] = data
}
}

return obj
Expand All @@ -100,15 +85,16 @@ function select(obj, key_arr)
// If we are at the end of the key array stack, return the object
if (key_arr.length == 0) return obj

// Get the object key and index that needs to be parsed
// Get the object key or index that needs to be parsed
var [key, ix] = process(key_arr.shift())

// If there is an object key, grab the object property
if (key) {
// If there is no object property associated with this key, return null
if (!obj.hasOwnProperty(key)) return null
// Otherwise, set the object to the object property
obj = obj[key]
var o = select(obj[key], key_arr)
return o
}

// If we need to deal with an array, then loop through and return recursive select for each
Expand All @@ -122,8 +108,6 @@ function select(obj, key_arr)
// Otherwise, return the results in the first array element
return o.shift()
}
// Recuse until we get to the bottom
return select(obj, key_arr)
}

function process(k)
Expand All @@ -145,9 +129,17 @@ function build_array(data, ix=0)
return arr
}

// Turns a key string (like key1.key2[].key3 into ['key1','key2[]','key3'])
// Turns a key string (like key1.key2[].key3 into ['key1','key2','[]','key3']...)
function parse(key, delimiter = '.') {
return key.split(delimiter)
var key_array = key.split(delimiter)

var keys = key_array.reduce(function(keys,current_key) {
var [k,ix] = process(current_key)
if (k) keys.push(k)
if (ix !== null) keys.push('[' + ix + ']')
return keys
}, [])
return keys
}


Expand Down
119 changes: 72 additions & 47 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,61 @@ var om = require('../')
, test = require('tape')
;

test("PROCESS - key array is not working for some reason", function(t) {
var key = 'items[].subitems[].subkey'
var expect = ['items', '[]', 'subitems','[]','subkey']
var result = om.parse(key)
t.deepEqual(result, expect);
t.end();

})
test('MAP - multiple levels of array indexes on both the from and to arrays', function (t) {
var obj =
{ Items:
[
{ SubItems:
[
{ SubKey: 'item 1 id a' },
{ SubKey: 'item 1 id b' }
]
},
{ SubItems:
[
{ SubKey: 'item 2 id a' },
{ SubKey: 'item 2 id b' }
]
}
]
}
var expect =
{ items:
[
{ subitems:
[
{ subkey: 'item 1 id a' },
{ subkey: 'item 1 id b' },
]
},
{ subitems:
[
{ subkey: 'item 2 id a' },
{ subkey: 'item 2 id b' },
]
}
]
}
var map = {
'Items[].SubItems[].SubKey': 'items[].subitems[].subkey'
};



var result = om(obj, map);

t.deepEqual(result, expect);
t.end();
});

test('process with simple key', function (t) {
var k = 'abc'
var expect = ['abc', null]
Expand Down Expand Up @@ -128,6 +183,23 @@ test('get value - two levels deep', function (t) {
t.deepEqual(result, expect);
t.end();
});
test('get value - two levels deep', function (t) {
var key = 'foo.baz.fog[].abc.def[].ghi';
var obj = {
"foo": {
"baz": {
"fog": "bar"
}
}
};

var expect = "bar";

var result = om.getKeyValue(obj, key);

t.deepEqual(result, expect);
t.end();
});

test('get value - one level deep and item is a array', function (t) {
var key = 'foo.baz[]';
Expand Down Expand Up @@ -2644,50 +2716,3 @@ var map = {
t.end();
});

test('Mapping multiple levels of array indexes on both the from and to arrays', function (t) {
var obj =
{ Items:
[
{ SubItems:
[
{ SubKey: 'item 1 id a' },
{ SubKey: 'item 1 id b' }
]
},
{ SubItems:
[
{ SubKey: 'item 2 id a' },
{ SubKey: 'item 2 id b' }
]
}
]
}
var expect =
{ items:
[
{ subitems:
[
{ subkey: 'item 1 id a' },
{ subkey: 'item 1 id b' },
]
},
{ subitems:
[
{ subkey: 'item 2 id a' },
{ subkey: 'item 2 id b' },
]
}
]
}
var map = {
'Items[].SubItems[].SubKey': 'items[].subitems[].subkey',
'Items[][].SubItems[]': 'items[]'
};



var result = om(obj, map);

t.deepEqual(result, expect);
t.end();
});

0 comments on commit 2c2147b

Please sign in to comment.