The concept is : you have given an array of strings like :
# The input will be always in the below format "x1>x2>x3...>xn=Integer" else it is invalid input #
private let input = [
"a>b>c=1",
"a>b>c=2",
"d>c=3",
"f>e=10",
"a>b=20", // Invalid, Node(b) has Child, cannot insert the value
"a>b>c>d=11", // Invalid , Node(c) has value, but trying to insert child, invalid case
"a>a>a=100"
]
(1). Let's consider the first input : "a>b>c=1" which consists of 2 parts based on "=" operator "a>b>c" and "1".
The first part is used for tree hierarchy where x>y means x is parent of y and the value "1" will be child of last node. It creates a tree like below for the first time as tree is empty at beginning.
( Root ) --> ("a") --> ("b") --> ("c") --> [1]
(2) Consider 2nd input : "a>b>c=2". Divide the input into 2 parts "a>b>c" and "2" based on "=". While processing "a>b>c", it's simply traversing because node("a"), node("b"), node("c") are in correct hierarchy and update the value node by appending value=2 so value([1,2]). Tree looks like :
( Root ) --> ("a") --> ("b") --> ("c") --> [1,2]
(3) Considering "d>c=3", the tree looks like :
( Root ) --> ("a") --> ("b") --> ("c") --> [1,2]
|
--> ("d") --> ("c") --> [3]
(4) Considering "a>b=20" input produce an ERROR because node("b") has a child node("c") so you cannot insert value([20]) for node("b"), So, don't process for this input. (no modification in tree)
(5) considering "a>b>c>d=11" input, produce an ERROR because node("c") has a Value([1,2]) child, you cannot add a node("d") as child of node("c"), So, don't process for this input. (no modification in tree)
You have to construct the Trie like below considering the above input.
{
"a" : { "b" : { "c" : [1,2] },
"a" : { "a" : [100] }
},
"d" : { "c" : [3] },
"f" : { "e" : [10] }
}
import Foundation
// Element must have either value or childDictionary, not at the same time
class Element {
var value : [Int]?
var childDictionary : Dictionary<String, Element>?
init(value : [Int]?, childKey : String?, childValue : Element? ) {
self.value = value
self.childDictionary = nil
if let childKey = childKey, let childValue = childValue {
var dict = Dictionary<String, Element>()
dict[childKey] = childValue
childDictionary = dict
}
}
}
class JsonCreator {
private var root : Element?
private let jsonInput = [
"a>b>c=1",
"a>b>c=2",
"d>c=3",
"f>e=10",
"a>b=20", // Invalid, Node(b) has Child, cannot insert the value
"a>b>c>d=11" // Invalid , Node(c) has value, but trying to insert child, invalid case
]
public func create() {
root = Element(value: nil, childKey: nil, childValue: nil) // root one
createJSON(input: jsonInput)
print("\n\n Output \n\n")
printJson(root: root)
}
private func createJSON(input : [String]) {
let rootJson = root
for each in input {
print("\n---------------------- New Input ----------------------\n")
// split the string into 2 parts
let parts = each.components(separatedBy: "=")
if parts.count > 1 { // go through the hierarchy
let literals = parts[0].filter{ $0 != ">" }
print(literals)
var traversal = rootJson
var char : Character!
var hasError = false
// literals
for i in 0..<literals.count {
char = literals[literals.index(literals.startIndex, offsetBy: i)]
print("Processing : \(char!)")
if let _ = traversal?.value {
print("ERROR : Node has value, but trying to insert child, invalid case")
hasError = true
break
} else if traversal?.childDictionary == nil {
print("Child is Empty : Do Insertion")
let node = Element(value: nil, childKey:nil , childValue: nil)
var dict = Dictionary<String, Element>()
dict[String(char)] = node
traversal?.childDictionary = dict
traversal = node // update traversal
} else if let isChildPresent = traversal?.childDictionary?.keys.contains(String(char)), !isChildPresent {
print("Child is not Empty, but not present in the hierary, Do Insertion")
let node = Element(value: nil, childKey:nil , childValue: nil)
traversal?.childDictionary?[String(char)] = node
traversal = node // update traversal
} else {
print("Child is not Empty, but present in the hierary: NO Insertion, only traverse ")
if let updateTraversal = traversal?.childDictionary?[String(char)] {
traversal = updateTraversal // update traversal
}
}
}
// Value
if let _ = char, let val = Int(parts[1]), !hasError {
print("value : \(val)")
if let _ = traversal?.childDictionary {
print("ERROR : Node has Child, cannot insert the value")
} else {
print("Append the value")
if let _ = traversal?.value {
traversal?.value?.append(val)
} else {
traversal?.value = [val]
}
}
}
root = rootJson // update root for every input
}
}
}
private func printJson(root : Element?) {
if let childDictionary = root?.childDictionary {
for each in childDictionary {
print("{ \(each.key) : ", terminator : "")
printJson(root: each.value)
print("}")
}
}
if let values = root?.value {
print("\(values)")
}
}
}
let jsonCreateObj = JsonCreator()
jsonCreateObj.create()
---------------------- New Input ----------------------
abc
Processing : a
Child is Empty : Do Insertion
Processing : b
Child is Empty : Do Insertion
Processing : c
Child is Empty : Do Insertion
value : 1
Append the value
---------------------- New Input ----------------------
abc
Processing : a
Child is not Empty, but present in the hierary: NO Insertion, only traverse
Processing : b
Child is not Empty, but present in the hierary: NO Insertion, only traverse
Processing : c
Child is not Empty, but present in the hierary: NO Insertion, only traverse
value : 2
Append the value
---------------------- New Input ----------------------
dc
Processing : d
Child is not Empty, but not present in the hierary, Do Insertion
Processing : c
Child is Empty : Do Insertion
value : 3
Append the value
---------------------- New Input ----------------------
fe
Processing : f
Child is not Empty, but not present in the hierary, Do Insertion
Processing : e
Child is Empty : Do Insertion
value : 10
Append the value
---------------------- New Input ----------------------
ab
Processing : a
Child is not Empty, but present in the hierary: NO Insertion, only traverse
Processing : b
Child is not Empty, but present in the hierary: NO Insertion, only traverse
value : 20
ERROR : Node has Child, cannot insert the value
---------------------- New Input ----------------------
abcd
Processing : a
Child is not Empty, but present in the hierary: NO Insertion, only traverse
Processing : b
Child is not Empty, but present in the hierary: NO Insertion, only traverse
Processing : c
Child is not Empty, but present in the hierary: NO Insertion, only traverse
Processing : d
ERROR : Node has value, but trying to insert child, invalid case
Output
{ d : { c : [3]
}
}
{ a : { b : { c : [1, 2]
}
}
}
{ f : { e : [10]
}
}