andecoder andecoder - 24 days ago 6
iOS Question

Create multidimentional array in swift with different datatypes

this is my first question here so forgive me if it is not very clear.

I am trying to create an array in swift that will store either arrays of arrays or an integer number.
The array is supposed to be a simple representation of the data I will be using which is basically a tree kind of data structure like so...

Array = [ [[ [2, 3] ], [ 1, 4 ], [ 2 ]],
[ 2 ], [[2, 5], [6, 1] ], 3 ]

In overall the arrays are the branches and the integers are the leaves

I've tried declaring them as optionals like so

var test2 = [[[Int]?]?]()


Or using typedef's but I still can't get it to work.

I'm workinking with swift 3, and I'm fearly new to iOS development so bare with me if my question should be a "well known" thing.

[Edit] Also, it should be possible to add new leaves to any of the arrays

Cheers

CRD CRD
Answer

Here is a solution based on enum, first declare the enum:

enum Node
{
    case leaf(Int)
    case branch([Node])
}

You can now write things such as:

let x = Node.leaf(42)
let y = Node.branch([Node.leaf(42), Node.leaf(24)])

However this is going to become laborious very quickly. Fortunately Swift allows conversions from literals, so we add:

extension Node : ExpressibleByIntegerLiteral
{
    init(integerLiteral value: Int)
    {
        self = .leaf(value)
    }
}

extension Node : ExpressibleByArrayLiteral
{
    init(arrayLiteral elements: Node...)
    {
        self = .branch(elements)
    }
}

And with those added we can now write the above two let statements as:

let x : Node = 42
let y : Node = [42, 24]

which is nicer. However if we print(y) we get:

branch([Node.leaf(42), Node.leaf(24)])

If you wish to pretty print that you can add:

extension Node : CustomStringConvertible
{
    var description : String
    {
        switch self
        {
            case .leaf(let value):
                    return value.description
            case .branch(let branches):
                    return branches.description
        }
    }
}

And now print(y) gives you:

[42, 24]

Finally your example:

let w : Node = [[[[2, 3]], [1, 4], [2]], [2], [[2, 5], [6, 1]], 3]

which prints as:

[[[[2, 3]], [1, 4], [2]], [2], [[2, 5], [6, 1]], 3]

You'll want to complete the enum type, with pedicures such as isNode etc., but that is the basic idea.

HTH