Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 136 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,142 @@ The expected output.
]
```

### Nested Array Handling

Suppose this is the data

```javascript
var data = {
"name": "Sarvpriy",
"users": [
{
id: "1",
name: "arya",
comments: [
{
text: "user id 1 comment no 1",
replies: [{
title: "reply 1 to user id 1 comment no 1"
}, {
title: "reply 2 to user id 1 comment no 1"
}]
},
{
text: "user id 1 comment no 2",
replies: [{
title: "reply 1 to user id 1 comment no 2"
}, {
title: "reply 2 to user id 1 comment no 2"
}]
}
]
}, {
id: "2",
name: "john",
comments: [
{
text: "user id 2 comment no 1",
replies: [{
title: "reply 1 to user id 2 comment no 1"
}, {
title: "reply 2 to user id 2 comment no 1"
}]
},
{
text: "user id 2 comment no 2",
replies: [{
title: "reply 1 to user id 2 comment no 2"
}, {
title: "reply 2 to user id 2 comment no 2"
}]
}
]
}
]
};
```

and you want this type of result
```javascript
{
"myname":"Sarvpriy",
"myusers": [{
"userid":"1",
"comments": [{
"mytext":"user id 1's comment no 1",
"myreplies": [{
"mytitle":"reply 1 to user id 1's comment no 1"
},{
"mytitle":"reply 2 to user id 1's comment no 1"
}]
},{
"mytext":"user id 1's comment no 2",
"myreplies": [{
"mytitle":"reply 1 to user id 1's comment no 2"
},{
"mytitle":"reply 2 to user id 1's comment no 2"
}]
}]
},{
"userid":"2",
"comments": [{
"mytext":"user id 2's comment no 1",
"myreplies": [{
"mytitle":"reply 1 to user id 2's comment no 1"
},{
"mytitle":"reply 2 to user id 2's comment no 1"
}]
},{
"mytext":"user id 2's comment no 2",
"myreplies": [{
"mytitle":"reply 1 to user id 2's comment no 2"
},{
"mytitle":"reply 2 to user id 2's comment no 2"
}]
}]
}]
}
```
This can be achieved through the `operate` params.
But there are two problems
- You cannot save your map object in other places ex. in Database.
- `operate` doesn't work on the nested level(more then one level deep).

no need to say that it is extreamly complex.
To acheive this the `map` object will look like this

```javascript
var map = {
"item" : {
"myname": "name",
"myusers[users]": {
"userid": "id",
"comments[comments]": {
"mytext": "text",
"myreplies[replies]": {
"mytitle": "title"
}
}
}
}
};
```
So in a nutshel the `map` object should be

```javascript
var map = {
"item": {
"new_arr_key[array_key_in_data]": { // `map` object b/w elements inside the new_arr_key and array_key_in_data
"some_new_key": "key_from_an_elem_in_array_key_in_data"
"nested_key[nested_key_inside_an_elem_in_array_key_in_data]": { // again `map` object
.
... // nesting goes on and on
}
}
}
}
```

Enjoy!

## Changelog
Expand Down
76 changes: 76 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
var _ = require('lodash');

var DataTransform = function(data, map){
if (_.hasIn(map, 'item') && _.isObject(map.item)) {
map.item = updateArrayKeys(map.item, data)
}

return {

Expand Down Expand Up @@ -171,6 +174,79 @@ var DataTransform = function(data, map){

};

const getSrcKey = function (newkey) {
if (newkey.indexOf('[') !== -1 && newkey.endsWith(']') ) {
return [
newkey.substring(0, newkey.indexOf('[')),
newkey.substring(newkey.indexOf('[') + 1, newkey.length - 1)
]
}
throw `SyntaxError: no source key found`
};

function updateArrayKeys(map, data) {
let newmap = {}

// loop thru map object
for(let [newkey, oldkey] of _.entries(map)) {

// find keys ending with ]
if (_.endsWith(newkey, ']')) {

// extract srckey, make newkey
var [ tempkey, srckey ] = getSrcKey(newkey)
newmap[tempkey] = map[newkey]

// start creating newoldkeys array
var newoldkey = []

// find length of srckey
_.get(data, srckey).forEach((elem, index) => {
var obj = {}

// loop thru the oldkey
for(let [oldkey_key, oldkey_val] of _.entries(oldkey)) {

// if any key ends with ]
if (_.endsWith(oldkey_key, ']')) {

// then prepend srckey with index after [
const newoldkey_key = `${oldkey_key.slice(0, oldkey_key.indexOf('[') + 1)}${srckey}[${index}].${oldkey_key.slice(oldkey_key.indexOf('[') + 1)}`
for (const [k, v] of _.entries(updateArrayKeys({ [newoldkey_key]: oldkey_val }, data))) {
obj[k] = v
}
}

// if val is string then prepend srckey with index
if (_.isString(oldkey_val)) {
obj[oldkey_key] = `${srckey}[${index}].${oldkey_val}`
}
// else leave
}

// push to newoldkey array
newoldkey.push(obj)
})

newmap[tempkey] = newoldkey

}
else if(_.isObject(oldkey) && !_.isArray(oldkey)) {
newmap[newkey] = updateArrayKeys(oldkey, data)
}
else if(_.isArray(oldkey)) {
newmap[newkey] = _.map(oldkey, (val) => {
if(_.isString(val)) return val
else if(_.isObject(val) && !_.isArray(val)) return updateArrayKeys(val, data)
})
}
else {
newmap[newkey] = oldkey
}
}
return newmap
}

exports.DataTransform = DataTransform;

exports.transform = function(data, map, context) {
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

149 changes: 149 additions & 0 deletions test/nestedArraySpec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
var DataTransform = require('../index.js').DataTransform,
transform = require('../index.js').transform,
_ = require("lodash");

var test1_data = {
"name": "Sarvpriy",
"users": [
{
id: "1",
name: "arya",
comments: [
{
text: "user id 1 comment no 1",
replies: [{
title: "reply 1 to user id 1 comment no 1"
}, {
title: "reply 2 to user id 1 comment no 1"
}]
},
{
text: "user id 1 comment no 2",
replies: [{
title: "reply 1 to user id 1 comment no 2"
}, {
title: "reply 2 to user id 1 comment no 2"
}]
}
]
}, {
id: "2",
name: "john",
comments: [
{
text: "user id 2 comment no 1",
replies: [{
title: "reply 1 to user id 2 comment no 1"
}, {
title: "reply 2 to user id 2 comment no 1"
}]
},
{
text: "user id 2 comment no 2",
replies: [{
title: "reply 1 to user id 2 comment no 2"
}, {
title: "reply 2 to user id 2 comment no 2"
}]
}
]
}
]
};

var test1_map = {
"item" : {
"myname": "name",
"myusers[users]": {
"userid": "id",
"comments[comments]": {
"mytext": "text",
"myreplies[replies]": {
"mytitle": "title"
}
}
}
}
};

var test1_expected = {
"myname":"Sarvpriy",
"myusers": [{
"userid":"1",
"comments": [{
"mytext":"user id 1 comment no 1",
"myreplies": [{
"mytitle":"reply 1 to user id 1 comment no 1"
},{
"mytitle":"reply 2 to user id 1 comment no 1"
}]
},{
"mytext":"user id 1 comment no 2",
"myreplies": [{
"mytitle":"reply 1 to user id 1 comment no 2"
},{
"mytitle":"reply 2 to user id 1 comment no 2"
}]
}]
},{
"userid":"2",
"comments": [{
"mytext":"user id 2 comment no 1",
"myreplies": [{
"mytitle":"reply 1 to user id 2 comment no 1"
},{
"mytitle":"reply 2 to user id 2 comment no 1"
}]
},{
"mytext":"user id 2 comment no 2",
"myreplies": [{
"mytitle":"reply 1 to user id 2 comment no 2"
},{
"mytitle":"reply 2 to user id 2 comment no 2"
}]
}]
}]
};

describe("node-json-transform", function() {

it("should change array keys and prefix the oldkeys with full srckey path", function() {
expect(transform(test1_data, test1_map)).toEqual(test1_expected);
});

});


var test2_data = {
"to": [{
"email": "sarvpriy.arya@gmail.com",
"name": "Sarvpriy Arya"
},{
"email": "sarvpriy.arya@gmail.com",
"name": "Sarvpriy Arya"
}]
};

var test2_map = {
"item": {
"personalizations": [{
"to[to]": {
"email": "email"
}
}]
}
};

var test2_expected = {"personalizations":[{"to":[{"email":"sarvpriy.arya@gmail.com"},{"email":"sarvpriy.arya@gmail.com"}]}]}

describe("node-json-transform", function() {

it("should work when top level is not an array", function() {
expect(transform(test2_data, test2_map)).toEqual(test2_expected);
});

it("should handle root object ex. { item: `payload`}", function() {
expect(transform({"payload": test2_data}, { "item": "payload"})).toEqual(test2_data);
});

});