Adding any two numberic tuples in swift

Viewed 630

I have created one function to add tuples which looks like (Int, Int).

func +<T : Numeric> (x: (T, T), y: (T, T)) -> (T, T) {
    return (x.0 + y.0, x.1 + y.1)
}

It works for (10, 20) + (15, 15)

Now what I need is to make an advancement to function to accept any variable length tuples of same length.

How is possible way?

At the end (12) + (23) and (10, 12, 16) + (11, 36, 25) should work.

2 Answers

Tuples need to have their number of elements determined at compile time, thus a variadic-like function won't work. You'll need to add overrides for the + operator, for each tuple size you need to support:

func +<T : Numeric> (x: (T, T), y: (T, T)) -> (T, T) {
    return (x.0 + y.0, x.1 + y.1)
}

func +<T : Numeric> (x: (T, T, T), y: (T, T, T)) -> (T, T, T) {
    return (x.0 + y.0, x.1 + y.1, x.2 + y.2)
}

func +<T : Numeric> (x: (T, T, T, T), y: (T, T, T, T)) -> (T, T, T, T) {
    return (x.0 + y.0, x.1 + y.1, x.2 + y.2, x.3 + y.3)
}

// and so on, ...

Alternatively, you can switch to other data types, like arrays, which allow a dynamic number of items:

infix operator ++ 

func ++<T: Numeric>(_ lhs: [T], _ rhs: [T]) -> [T] {
    return zip(lhs, rhs).map { $0.0 + $0.1 }
}

print([10, 12, 16] ++ [11, 36, 25]) // [21, 48, 41]

Caveats of this approach:

  • you need to use a different operator, since is + already defined for arrays, and it concatenates the arrays instead of individually summing the corresponding elements
  • if the two arrays have different sizes, then the result will have the size of the smaller arrays of the two input ones.

You can use the Array solution as suggested by @Cristik or you can also make use of closure returning variadic function like:

func add<T : Numeric>(_ a: T...) -> (_ b: T...) -> [T] {
    return { (b: T...) -> [T] in
        return zip(a, b).map { $0.0 + $0.1 }
    }
}

let sum = add(1, 2,3)(4, 5, 6)

print(sum)
Related