Wingzero
Wingzero

Reputation: 9754

replacement for c-loop if the array may be nil for swift 2.2 and above

So C-loop was deprecated in swift 2.2 and will be removed in swift 3. I'm against it but have to live with it.

I had a function like below:

func levelOrder(root: TreeNode?) -> [[Int]] {
    guard root != nil else { return [] }

    let leftArr = levelOrder(root!.left)
    let rightArr = levelOrder(root!.right)
    var merged = [[Int]]()
    merged.append([root!.val])
    for i in 0...max(leftArr.count, rightArr.count)
    {
        var current = [Int]()
        let currentLeft: [Int]? = i < leftArr.count ? leftArr[i] : nil
        let currentRight: [Int]? = i < rightArr.count ? rightArr[i] : nil
        for var j = 0; j < currentLeft?.count; j++
        {
            current.append(currentLeft![j])
        }
        for var j = 0; j < currentRight?.count; j++
        {
            current.append(currentRight![j])
        }
        if current.count > 0
        {
            merged.append(current)
        }
    }
    return merged
}

So for the inner for loop, I am using c style loop, it is perfect that if currentLeft is nil, the for loop will never get executed at all, so the code is clean and elegant.

Now the question is, in order to use swift loops, I have to use a if condition to check if the array is nil, which is annoying. Is there any good solution to replace the c loop without introducing more if condition like mine?

Upvotes: 0

Views: 70

Answers (2)

Wain
Wain

Reputation: 119031

Why not simplify and shorten, because you don't need your own inner loops:

for i in 0...max(leftArr.count, rightArr.count)
{
    var current = [Int]()

    if i < leftArr.count {
        current.appendContentsOf(leftArr[i])
    }
    if i < rightArr.count {
        current.appendContentsOf(rightArr[i])
    }

    if current.count > 0
    {
        merged.append(current)
    }
}

Upvotes: 2

Sulthan
Sulthan

Reputation: 130132

For your use case, the simplest solution is using an empty array instead of nil.

let currentLeft: [Int] = i < leftArr.count ? leftArr[i] : []
let currentRight: [Int] = i < rightArr.count ? rightArr[i] : []

Also, you might use a more functional approach:

currentLeft.forEach {
   current.append($0)
}

or just:

let current = currentLeft + currentRight

Upvotes: 3

Related Questions