将2D数组展开为树形布局

时间:2015-12-31 07:32:05

标签: json algorithm sorting multidimensional-array

我有一个二维数组,现在看起来像这样(样本数据,而不是实际字段):

[
    ["key1": "val1" ,"key2": "val1" ,"key3": "val1"],
    ["key1": "val1" ,"key2": "val1" ,"key3": "val2"],
    ["key1": "val1" ,"key2": "val2" ,"key3": "val3"],
    ["key1": "val1" ,"key2": "val2" ,"key3": "val4"],
    ["key1": "val2" ,"key2": "val3" ,"key3": "val5"],
    ["key1": "val2" ,"key2": "val3" ,"key3": "val6"],
    ["key1": "val2" ,"key2": "val4" ,"key3": "val7"],
    ["key1": "val2" ,"key2": "val4" ,"key3": "val8"]
]

数据基本上随着数组越来越大而分支出来,我想创建一个算法,可以将其解析成更适合这种类型数据的格式,特别是树。 / p>

这就是我想要的结果:

{
    "key1": [
        {"val1": [
            {"key2": [
                {"val1": [
                    {"key3": "val1"},
                    {"key3": "val2"}
                ]},
                {"val2": [
                    {"key3": "val3"},
                    {"key3": "val4"}
                ]}
            ]}
        ]},
        {"val2": [
            {"key2": [
                {"val3": [
                    {"key3": "val5"},
                    {"key3": "val6"}
                ]},
                {"val4": [
                    {"key3": "val7"},
                    {"key3": "val8"}
                ]}
            ]}
        ]}
    ]
}

有人能指出我这样做的大方向吗?或者有更好的方法来排序这种类型的数据?谢谢!

编辑:我想补充说深度是动态的,这意味着每行中没有设定数量的键/值对。数据还可以分支到两个以上的不同键/值对。例如,一个键可以有五个不同的值,它们下面有三个不同的键。

1 个答案:

答案 0 :(得分:1)

此代码应该有效。它通过并将输入组织成一个深度嵌套的数组,然后将该数组分开到您正在寻找的树中。

var twoDimArray = [
        ["key1": "val1" ,"key2": "val1" ,"key3": "val1"],
        ["key1": "val1" ,"key2": "val1" ,"key3": "val2"],
        ["key1": "val1" ,"key2": "val2" ,"key3": "val3"],
        ["key1": "val1" ,"key2": "val2" ,"key3": "val4"],
        ["key1": "val2" ,"key2": "val3" ,"key3": "val5"],
        ["key1": "val2" ,"key2": "val3" ,"key3": "val6"],
        ["key1": "val2" ,"key2": "val4" ,"key3": "val7"],
        ["key1": "val2" ,"key2": "val4" ,"key3": "val8"]
    ]

    var arrayOfKeys = ["key1", "key2", "key3"]

    var combinedArray: Array<String> = []
    for dict in twoDimArray {
        for key in arrayOfKeys {
            combinedArray.append(key)
            combinedArray.append(dict[key]!)
        }
    }

    print(combinedArray)

    for var index = 0; index < combinedArray.count - 2; index = index + 2 {
        let key = combinedArray[index]
        let value = combinedArray[index + 1]
        if combinedArray.count == 2 || combinedArray.count % 2 == 1 {
            break
        }
        let start = index + 2
        for var index2 = start; index2 < combinedArray.count; index2 = index2 + 2 {
            let key2 = combinedArray[index2]
            let value2 = combinedArray[index2 + 1]
            if key == key2 && value == value2 {
                combinedArray.removeAtIndex(index2)
                combinedArray.removeAtIndex(index2)
            }
        }
    }

    var doubledArray: Array<Array<String>> = []

    for var index = 0; index < combinedArray.count; index = index + 2 {
        doubledArray.append([combinedArray[index], combinedArray[index+1]])
    }

    var result: Array<Array<Array<Dictionary<String, String>>>> = []
    var currentKey = arrayOfKeys.first!
    var currentArray: Array<Array<Dictionary<String, String>>> = []

    var index2 = 0
    for var index = 0; index < arrayOfKeys.count; index++ {
        currentArray = []
        currentKey = arrayOfKeys[index]

        var lastFind = -2
        var tempArray: Array<Dictionary<String, String>> = []
        for var index3 = 0; index3 < doubledArray.count; index3++ {
            var arr = doubledArray[index3]
            if arr[0] == currentKey {
                lastFind = index3
                tempArray.append([arr[0]:arr[1]])
                if index3 == doubledArray.count - 1 {
                    currentArray.append((tempArray as NSArray).copy() as! Array<Dictionary<String, String>>)
                }
            }
            else if lastFind == index3 - 1 {
                currentArray.append((tempArray as NSArray).copy() as! Array<Dictionary<String, String>>)
                tempArray = []
            }
        }

        result.append(currentArray)
        index2++
    }
    print(result)

    var arrayTree: Array<Array<Array<Dictionary<String, String>>>>
    var resultTree = NSDictionary()
    var v: AnyObject = []

    class Tree: NSObject {
        var value: String = ""
        var elements: AnyObject = []

        func convertToDictionary() -> NSDictionary {
            var values: Array<NSDictionary> = []

            for item in self.elements as! NSArray {
                if item is Tree {
                    values.append((item as! Tree).convertToDictionary())
                }
                else {
                    values.append(item as! NSDictionary)
                }
            }

            return [value:elements]
        }
    }


    func createElementsForTree(input: Array<Array<Array<Dictionary<String, String>>>>) -> Tree {
        var trees: Array<Tree> = []

        for var index = 0; index < result[result.count - 1].count; index++ {
            let array = result[result.count - 1][index]
            let secondIndex = Int(ceil(Float(index)/2))
            let value = result[result.count - 2][secondIndex]

            let newTree = Tree()
            newTree.value = (value[0] as NSDictionary).allValues[0] as! String
            newTree.elements = array
            trees.append(newTree)
        }
        print(trees)
        var isKey = true
        for var reverseIndex = result.count - 2; reverseIndex >= 0;  {
            for var index = 0; index < result[reverseIndex].count; index++ {
                let arr = result[reverseIndex][index]
                let tree = Tree()
                if isKey {
                    tree.value = (arr.first! as NSDictionary).allKeys[0] as! String
                    var elements = [trees.removeFirst()]
                    if reverseIndex != result.count - 2 {
                        elements.append(trees.removeFirst())
                    }
                    tree.elements = elements
                    trees.append(tree)
                }
                else {
                    tree.value = (arr.first! as NSDictionary).allValues[0] as! String
                    tree.elements = [trees.removeFirst()]
                    trees.append(tree)
                }
            }
            if isKey {
                reverseIndex--
                isKey = false
            }
            else {
                isKey = true
            }
        }

        let tree = Tree()
        tree.value = (result[0][0][0] as NSDictionary).allKeys[0] as! String
        tree.elements = trees
        return tree
    }

    let objectTree = createElementsForTree(result)

    let finalResult = objectTree.convertToDictionary()

    print(finalResult)