我遇到了麻烦,提出了一种算法将数组转换为字典。该数组具有以下结构:
let array = [
Parameter(type: "string", name: "name1", value: "bar", parent: nil),
Parameter(type: "bool", name: "name2", value: true, parent: nil),
Parameter(type: "array", name: "name3", value: [], parent: nil),
Parameter(type: "bool", name: "name3.1", value: false, parent: "name3"),
Parameter(type: "array", name: "name3.2", value: [], parent: "name3"),
Parameter(type: "string", name: "name4.1", value: "baz", parent: "name3.2")
]
Parameter
是一个简单结构体。输出应该是一个字典。在上面给出的例子中,应该是这样的:
[
"name1": "bar",
"name2": true,
"name3": [
"name3.1": false,
"name3.2": [
"name4.1": "baz"
]
]
]
在给定结构没有父结构的情况下,实现它是非常基本的,但我在实现另一种情况时遇到了麻烦:
func makeDictionary(from array: [Parameter]) -> [String: Any] {
var dictionary: [String: Any] = [:]
for parameter in array {
if let parent = parameter.parent {
#warning("how to handle this case?")
} else {
dictionary[parameter.name] = parameter.value
}
}
return dictionary
}
由于数组可能是无序的,我该如何处理接收到"name "数组"name3.2"或者数组"name3"在我的字典中是否已创建并可用?
为了解决这个问题,我们需要使用递归来连接父对象和子对象。这里是一个解决方案,使用一个普通函数迭代顶级父类(即没有父类的对象),然后为任何类型为&;array&;的父类调用递归函数,即可能有子类的父类。
//Main function
func makeDictionary(from array: [Parameter]) -> [String: Any] {
let parents = array.filter { $0.parent == nil }
var dictionary = [String: Any]()
for parent in parents {
if parent.type == "array" {
let child = allChildren(for: array.filter { $0.parent == parent.name }, in: array)
dictionary[parent.name] = child
} else {
dictionary[parent.name] = parent.value
}
}
return dictionary
}
//Recursive function
func allChildren(for children: [Parameter], in array: [Parameter]) -> [[String: Any]] {
var result = [[String: Any]]()
for child in children {
if child.type == "array" {
let children = allChildren(for: array.filter { $0.parent == child.name }, in: array)
result.append([child.name: children])
} else {
result.append([child.name: child.value])
}
}
return result
}
例子let dictionary = makeDictionary(from: array)
print(dictionary)
["name3"[["name3.1"假],["name3.2"[["name4.1"baz"]]],"name2":真的,"name1":"bar"]