diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..690ee40 --- /dev/null +++ b/composer.json @@ -0,0 +1,11 @@ +{ + "autoload": { + "classmap": [ + "src/" + ] + }, + "require-dev": { + "phpunit/phpunit": "^7", + "squizlabs/php_codesniffer": "*" + } +} diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..0f1aa6c --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,29 @@ + + + + + tests + + + + + .. + + + + . + + ./vendor + ./tests + ./SDK-PHP-master + + + + diff --git a/src/SkillsAssessment.php b/src/SkillsAssessment.php new file mode 100644 index 0000000..ab86e93 --- /dev/null +++ b/src/SkillsAssessment.php @@ -0,0 +1,130 @@ + + * @copyright 2019 Ontraport - All Rights Reserved + * @license http://www.ontraport.com/ Proprietary + * @link None + */ + +/** + * SkillsAssessment class + * + * @category None + * @package None + * @author Brad Dobson + * @license http://www.ontraport.com/ Proprietary + * @link None + */ +class SkillsAssessment +{ + + /* + * Notes + * - I departed slightly from the test description: + * - the examples used single quotes. Since it wasn't explicitly stated + * I assumed I could user double quotes so that the data could be easily + * parsed by json functions. It would be trivial to add something to + * convert the quotes first. + * - Since the json function allows it to pull the whole thing in as an + * associative array, I've interpreted 'container' to mean 'array', which + * allows the traversal to be a little easier. + * - I wouldn't have necessarily wrapped this in a class, but phpunit only + * really seems to like testing classes. + */ + + /** + * Function flattenArray + * + * @param array $inputArr Input array + * + * @return array Walk a multidimensional array (basically a tree). Keep + * running track of the current stack of levels and their + * names. For each leaf, output the merged stack path as a + * single key with the associated value. + */ + function flattenArray($inputArr) + { + $elemStack = array(); + $pathStr = ""; + $outputArr = array(); + $currentElem = $inputArr; + $key = key($currentElem); + while ($currentElem != null) { + if (array_key_exists($key, $currentElem) + && is_array($currentElem[$key]) + ) { + /* + * subarray: push onto the stack, build the path string deeper, + * walk to next deeper level. + */ + array_push($elemStack, $currentElem); + $pathStr .= $key . "/"; + $currentElem = $currentElem[$key]; + } else { + if (array_key_exists($key, $currentElem) + && $currentElem[$key] != "" + ) { + /* leaf: make the assignment in the flattened array */ + $outputArr[$pathStr . $key] = $currentElem[$key]; + } + if (next($currentElem) === false) { + /* + * done with subarray: pop from stack, shorten path string + * walk to next at this level. + */ + $currentElem = array_pop($elemStack); + $lastslash = strrpos($pathStr, "/", strlen($pathStr) - 1); + $pathStr = substr($pathStr, 0, $lastslash); + if ($currentElem != null) { + next($currentElem); + } + } + } + if ($currentElem != null) { + $key = key($currentElem); + } + } + return ($outputArr); + } + + /** + * Function deepenArray + * + * @param array $inputArr Input array + * + * @return array Take a single-dimensional array where each key itself + * represents further subarrays. Explode each key and create + * a multidimensional array structure. This reverses + * flattenArray(). Also considered 'embiggenArray()' as a more + * cromulent function name. + */ + function deepenArray($inputArr) + { + $outputArr = array(); + foreach ($inputArr as $arrayLevels => $value) { + $current = &$outputArr; + + /* Create an array of levels from the original key value */ + $keys = explode("/", $arrayLevels); + foreach ($keys as $key) { + /* build the subarray levels as we go */ + if (! isset($current[$key])) { + $current[$key] = array(); + } + $current = &$current[$key]; + } + /* do the assignment */ + $current = $value; + } + return ($outputArr); + } +} + + +?> \ No newline at end of file diff --git a/tests/SkillsAssessmentTest.php b/tests/SkillsAssessmentTest.php new file mode 100644 index 0000000..6a46cb6 --- /dev/null +++ b/tests/SkillsAssessmentTest.php @@ -0,0 +1,66 @@ +SK = new SkillsAssessment(); + $obj=array(); + $deep = $this->SK->deepenArray($obj); + $this->assertEquals(empty($deep),true); + } + + /** + * @test + * @return void + */ + public function testFlattenEmptyArray() + { + $this->SK = new SkillsAssessment(); + $obj=array(); + $flat = $this->SK->flattenArray($obj); + $this->assertEquals(empty($flat),true); + } + + /** + * @test + * @return void + */ + public function testFlattenBasicInput() + { + $this->SK = new SkillsAssessment(); + $json = file_get_contents("tests/json1.txt"); + $obj = json_decode($json, true); + $flat = $this->SK->flattenArray($obj); + $this->assertEquals($flat["one/two"], 3); + $this->assertEquals($flat["one/four/2"], 7); + } + + /** + * @test + * @return void + */ + public function testDeepenBasicInput() + { + $this->SK = new SkillsAssessment(); + $json = file_get_contents("tests/json1a.txt"); + $obj = json_decode($json, true); + $deep = $this->SK->deepenArray($obj); + $this->assertEquals($deep["one"]["two"], 3); + $this->assertEquals($deep["one"]["four"][1], 6); + $this->assertEquals($deep["eight"]["nine"]["ten"], 11); + } + +} +?> \ No newline at end of file diff --git a/tests/json1.txt b/tests/json1.txt new file mode 100644 index 0000000..06d33bd --- /dev/null +++ b/tests/json1.txt @@ -0,0 +1,14 @@ +{ + "one": + { + "two": 3, + "four": [ 5,6,7] + }, + "eight": + { + "nine": + { + "ten": 11 + } + } +} diff --git a/tests/json1a.txt b/tests/json1a.txt new file mode 100644 index 0000000..7000d2a --- /dev/null +++ b/tests/json1a.txt @@ -0,0 +1,7 @@ +{ + "one/two":3, + "one/four/0":5, + "one/four/1":6, + "one/four/2":7, + "eight/nine/ten":11 +}