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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules/
package-lock.json
57 changes: 18 additions & 39 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,46 +1,25 @@
# ONTRAPORT Backend Skills Test
## Object Converter

Hi, Thanks for checking us out
This tool converts the multidimensional container to single list object and vice versa. The code is written in
JavaScript. Mocha and Chai is used for unit testing.

If you're interested in applying for the **Backend Engineer** team a great first step is to complete a brief test to allow us to assess your skills. You will find our Backend Engineer test below. Any language is fine, please note there are **two** questions:
**Steps to run the application:**

1) Write a function that accepts a multi-dimensional container of any size and converts it into a one dimensional associative array whose keys are strings representing their value's path in the original container.
1. Clone/Download the repository.

E.G.
2. Download the dependencies.
```
npm install
```

```
{
'one':
{
'two': 3,
'four': [ 5,6,7]
},
'eight':
{
'nine':
{
'ten':11
}
}
}
```
3. Run the main.js file using node.
```
node main.js
```

turns into:
**Steps to run unit test for this application:**

```
{
'one/two':3,
'one/four/0':5,
'one/four/1':6,
'one/four/2':7,
'eight/nine/ten':11
}
```

2) Now write a separate function to do the reverse.

We want you to fork and then create a pull-reqest against this repository and we'll review it.

Thanks and good luck!

Ontraport Careers Team
1. Run the unit test using below command.
```
npm test
```
55 changes: 55 additions & 0 deletions converters/listToObjectConverter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**
* Convert single array to multidimensional container
*
* @param objList
* @returns new object list
*/
function listToObjectConverter(objList) {
const result = {}

// loop over the object path
for (const objectPath in objList) {
// split the path into keys
const keyList = objectPath.split('/')

// create nested object and append the result
let nestedObject = result
let key

// iterate until second last index
while (keyList.length > 1) {
// poll the keys from the list
key = keyList.shift()

// check if the last key is index
if (!isNaN(keyList[0])) {

// check if the key is present or not
if (!nestedObject.hasOwnProperty(key)) {
// create list
nestedObject[key] = []
}

// push the value to the list
nestedObject[key].push(objList[objectPath])
} else {
// check whether the key of the previous object is present or not
// create new object
nestedObject[key] = nestedObject[key] || {}
}

// update the nested object with the new object
nestedObject = nestedObject[key]
}

// check whether the last key is not an index.
if (isNaN(keyList[0])) {
// set another key with the appropriate value
nestedObject[keyList[0]] = objList[objectPath]
}
}

return result
}

module.exports = listToObjectConverter;
38 changes: 38 additions & 0 deletions converters/objectToListConverter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* Convert multidimensional container to single array
*
* @param jsonObj
* @param objPath
* @param objList
* @returns {{}}
*/
function objectToListConverter(jsonObj, objPath = null, objList = {}) {

// check whether the last object is number
// if its number then its the index
if (typeof jsonObj === 'number') {
// append the object
objList = {...objList, [objPath]: jsonObj}
} else if (jsonObj == null) {
// base condition
return objList
}

// loop over json object
for (const [key, value] of Object.entries(jsonObj)) {
// initially objPath will be null so dont concatenate object path
if (objPath === null) {
// pass the key as object path
objList = objectToListConverter(value, key, objList)
} else {
// append the object path with key
// so that we can get complete path
objList = objectToListConverter(value, `${objPath}/${key}`, objList)
}
}

// return new objectList
return objList
}

module.exports = objectToListConverter;
36 changes: 36 additions & 0 deletions main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
const objectToListConverter = require("./converters/objectToListConverter");
const listToObjectConverter = require("./converters/listToObjectConverter");

// predefined json object
let jsonObj = {
one: {
two: 3,
four: [5, 6, 7],
},
eight: {
nine: {
ten: 11,
},
},
};

/**
* This function converts multidimensional container to single array
* and again converts the single array to multidimensional container.
*
* @param jsonObj
* @returns {*|{}}
*/
function main(jsonObj) {
let list = objectToListConverter(jsonObj)
let newJsonObj = listToObjectConverter(list)

console.log(list)
console.log(newJsonObj)

return newJsonObj
}

main(jsonObj)

module.exports = main;
16 changes: 16 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "ontraport",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "mocha --reporter spec --recursive"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"chai": "^4.2.0",
"mocha": "^8.2.1"
}
}
71 changes: 71 additions & 0 deletions test/testConverters/testListToObjectConverter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
const expect = require("chai").expect;
const listToObjectConverter = require('../../converters/listToObjectConverter');

let objListType1 = {
'one/two': 3,
'one/four/0': 5,
'one/four/1': 6,
'one/four/2': 7,
'eight/nine/ten': 11
}

describe("Test listToObjectConverter", function () {
it("converts list to object of objListType1", function () {
const newJsonObj = listToObjectConverter(objListType1);

expect(newJsonObj).to.eql({
one: {
two: 3,
four: [5, 6, 7]
}, eight: {
nine: {
ten: 11
}
}
}
);
});
});

let objListType2 = {
'one/two': 3,
'one/four/five/six/seven/0': 8,
'eight': 11
}

describe("Test listToObjectConverter", function () {
it("converts list to object of objListType2", function () {
const newJsonObj = listToObjectConverter(objListType2);

expect(newJsonObj).to.eql({
one: {
two: 3,
four: {
five: {
six: {
seven: [8]
}
}
}
},
eight: 11
}
);
});
});

describe("Test listToObjectConverter", function () {
it("converts list to object with empty list", function () {
const newJsonObj = listToObjectConverter({});

expect(newJsonObj).to.eql({});
});
});

describe("Test listToObjectConverter", function () {
it("converts list to object with list parameter as null", function () {
const newJsonObj = listToObjectConverter(null);

expect(newJsonObj).to.eql({});
});
});
71 changes: 71 additions & 0 deletions test/testConverters/testObjectToListConverter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
const expect = require("chai").expect;
const objectToListConverter = require("../../converters/objectToListConverter");

let objListType1 = {
one: {
two: 3,
four: [5, 6, 7],
},
eight: {
nine: {
ten: 11,
},
},
}

describe("Test objectToListConverter", function () {
it("converts object to list of objListType1", function () {
const list = objectToListConverter(objListType1);
expect(list).to.eql({
'one/two': 3,
'one/four/0': 5,
'one/four/1': 6,
'one/four/2': 7,
'eight/nine/ten': 11
}
)
})
})

let objListType2 = {
one: {
two: 3,
four: {
five: {
six: {
seven: [8]
}
}
}
},
eight: 11
}

describe("Test listToObjectConverter", function () {
it("converts list to object of objListType2", function () {
const list = objectToListConverter(objListType2);

expect(list).to.eql({
'one/two': 3,
'one/four/five/six/seven/0': 8,
'eight': 11
}
)
})
})

describe("Test objectToListConverter", function () {
it("converts object to list with empty object", function () {
const list = objectToListConverter({});

expect(list).to.eql({});
})
})

describe("Test objectToListConverter", function () {
it("converts object to list with object parameter as null", function () {
const list = objectToListConverter(null);

expect(list).to.eql({});
})
})
38 changes: 38 additions & 0 deletions test/testMain.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
const expect = require("chai").expect;
const main = require("../main");

let objListType1 = {
one: {
two: 3,
four: [5, 6, 7, 8, 9, 10],
},
eight: {
nine: {
ten: 11,
},
},
}

describe("Test main", function () {
it("integration test", function () {
const list = main(objListType1);

expect(list).to.eql(objListType1)
})
})

describe("Test main", function () {
it("integration test with object parameter as empty", function () {
const list = main({});

expect(list).to.eql({});
})
})

describe("Test main", function () {
it("integration test with object parameter as null", function () {
const list = main(null);

expect(list).to.eql({});
})
})