Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Not sure how to avoid duplicating code here

Tags:

arrays

swift

I have this bit of code, which works great and does exactly what I want it to do:

            if condition1 {
                array1 += [array1[i-n]]
            } else {
                array1 += [Int (arc4random_uniform(7))]
                if array1[i] >= array1[i-n] {
                    array1[i] += 1
                }
            } //same logic, different condition and array
            if condition2 {
                array2 += [array2[i-n]]
            } else {
                array2 += [Int (arc4random_uniform(7))]
                if array2[i] >= array2[i-n] {
                    array2[i] += 1
                }
            }

But I'm doing the exact same thing twice, just with a different condition and different array. How can I avoid duplicating the logic? I tried packaging it up as an array of two tuples:

[ (condition1, array1) , (condition2, array2) ]

and I put that in a for loop:

for tuple in [ (condition1, array1) , (condition2, array2) ] {
    var (condition, array) = tuple
    if condition {
        array += [array[i-n]]
    } else {
        array += [Int (arc4random_uniform(7))]
        if array[i] >= array[i-n] {
            array[i] += 1
        }
    }
}

and that compiled, but it seems as though the array was copied, in other words changing "array" did not affect "array1" or "array2". I'd tried other variations of that using tuple.0 and tuple.1 notation, but could not get that to compile. So then I tried using NSArrays instead of native Swift arrays ... but I couldn't figure out how to do that the right way, and in any case thought there must be a simpler way to do it.

Is there a succinct way of restating my original code so as not to duplicate the logic?

like image 833
user1224598 Avatar asked Jan 12 '15 15:01

user1224598


2 Answers

Curry it!

func func1(var a: [Int]) -> [Int] {
    a += [a[i-n]]
    return a
}

func func2(var a: [Int]) -> [Int] {
    a+= [Int (arc4random_uniform(7))]
    if a[i] >= a[i-n] {
        a[i] += 1
    }
    return a
}

func function(condition: Bool) -> [Int] -> [Int] {
    switch condition {
    case true:
        return func1
    case false:
        return func2
    }
 }

array1 = function(condition1)(array1)
array2 = function(condition2)(array2)

(and the same inout stuff that andyvn22 mentioned can apply here, too.)

like image 143
Aaron Rasmussen Avatar answered Oct 06 '22 09:10

Aaron Rasmussen


func alteredArray(var array:[Int], condition: Bool) -> [Int] {
    if condition {
        array += [array[i-n]]
    } else {
        array += [Int (arc4random_uniform(7))]
        if array[i] >= array[i-n] {
            array[i] += 1
        }
    }
    return array
}

array1 = alteredArray(array1, condition1)
array2 = alteredArray(array2, condition2)

Or, if you're feeling terse, rename the function, make array an inout parameter, remove the return, and call it as:

alterArray(&array1, condition1)
alterArray(&array2, condition1)
like image 35
andyvn22 Avatar answered Oct 06 '22 08:10

andyvn22