From a503991a666d3b8569a8ba8e8ef1910479636625 Mon Sep 17 00:00:00 2001 From: Sarvpriy Arya Date: Thu, 5 Aug 2021 20:03:04 +0530 Subject: [PATCH 1/4] add ability to write nested array --- README.md | 136 ++++++++++++++++++++++++++++++++++++++++ index.js | 66 +++++++++++++++++++ package-lock.json | 2 +- test/nestedArraySpec.js | 114 +++++++++++++++++++++++++++++++++ 4 files changed, 317 insertions(+), 1 deletion(-) create mode 100644 test/nestedArraySpec.js diff --git a/README.md b/README.md index 181ce59..f934c20 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/index.js b/index.js index e34541b..b528ba1 100644 --- a/index.js +++ b/index.js @@ -3,6 +3,9 @@ var _ = require('lodash'); var DataTransform = function(data, map){ + if (_.hasIn(map, 'item')) { + map.item = updateArrayKeys(map.item, data) + } return { @@ -171,6 +174,69 @@ 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 { + newmap[newkey] = oldkey + } + } + return newmap +} + exports.DataTransform = DataTransform; exports.transform = function(data, map, context) { diff --git a/package-lock.json b/package-lock.json index cd27c55..f952a93 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "node-json-transform", - "version": "1.1.1", + "version": "1.1.2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/test/nestedArraySpec.js b/test/nestedArraySpec.js new file mode 100644 index 0000000..adf117d --- /dev/null +++ b/test/nestedArraySpec.js @@ -0,0 +1,114 @@ +var DataTransform = require('../index.js').DataTransform, + transform = require('../index.js').transform, + _ = require("lodash"); + +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" + }] + } + ] + } + ] +}; + +var map = { + "item" : { + "myname": "name", + "myusers[users]": { + "userid": "id", + "comments[comments]": { + "mytext": "text", + "myreplies[replies]": { + "mytitle": "title" + } + } + } + } + }; + +var 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(data, map)).toEqual(expected); + }); + +}); From 7eaa50005b601867cc3e22711dfe46713ff0b3ae Mon Sep 17 00:00:00 2001 From: Sarvpriy Arya Date: Sun, 8 Aug 2021 18:43:23 +0530 Subject: [PATCH 2/4] fix: handle objects and array at top level even if they do not have a corresponding array --- index.js | 12 +++++++++++- test/nestedArraySpec.js | 39 +++++++++++++++++++++++++++++++++++---- 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/index.js b/index.js index b528ba1..3d778bf 100644 --- a/index.js +++ b/index.js @@ -230,7 +230,17 @@ function updateArrayKeys(map, data) { newmap[tempkey] = newoldkey - } else { + } + 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 } } diff --git a/test/nestedArraySpec.js b/test/nestedArraySpec.js index adf117d..e572b85 100644 --- a/test/nestedArraySpec.js +++ b/test/nestedArraySpec.js @@ -2,7 +2,7 @@ var DataTransform = require('../index.js').DataTransform, transform = require('../index.js').transform, _ = require("lodash"); -var data = { +var test1_data = { "name": "Sarvpriy", "users": [ { @@ -51,7 +51,7 @@ var data = { ] }; -var map = { +var test1_map = { "item" : { "myname": "name", "myusers[users]": { @@ -66,7 +66,7 @@ var map = { } }; -var expected = { +var test1_expected = { "myname":"Sarvpriy", "myusers": [{ "userid":"1", @@ -108,7 +108,38 @@ var expected = { describe("node-json-transform", function() { it("should change array keys and prefix the oldkeys with full srckey path", function() { - expect(transform(data, map)).toEqual(expected); + 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); + }); + +}); From 16a1557ed46fd454e4d6947cd083f4bb98a0f9a4 Mon Sep 17 00:00:00 2001 From: Sarvpriy Arya Date: Sun, 8 Aug 2021 23:38:55 +0530 Subject: [PATCH 3/4] fix: handle root object ex. { item: } --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index 3d778bf..fa2356e 100644 --- a/index.js +++ b/index.js @@ -3,7 +3,7 @@ var _ = require('lodash'); var DataTransform = function(data, map){ - if (_.hasIn(map, 'item')) { + if (_.hasIn(map, 'item') && _.isObject(map.item)) { map.item = updateArrayKeys(map.item, data) } From 69968c42fed337885db462619c336641d7fe002f Mon Sep 17 00:00:00 2001 From: Sarvpriy Arya Date: Sun, 8 Aug 2021 23:41:32 +0530 Subject: [PATCH 4/4] add test case for handle root object ex. { item: } --- test/nestedArraySpec.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/nestedArraySpec.js b/test/nestedArraySpec.js index e572b85..74fe00b 100644 --- a/test/nestedArraySpec.js +++ b/test/nestedArraySpec.js @@ -142,4 +142,8 @@ describe("node-json-transform", 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); + }); + });