# How to avoid the duplication of a function in order to simplify code

Consider this code:

``````struct Element1 {
var sky: Int
var bird: [Int]
var point: [[Double]]
var weight: [Double]
}

struct Element2 {
var ocean: Int
var whale: [Int]
var point: [Double]
var weight: [Double]
}

func someFunction1(_ arg1: Int, _ arg2: Int, _ element: Element1) {
// do something... and then call:
someFunction2(element.point, element.weight)
// then continue doing more stuff...
}

func someFunction1(_ arg1: Int, _ arg2: Int, _ element: Element2) {
// do something... and then call:
someFunction2(element.point, element.weight)
// then continue doing more stuff...
}

func someFunction2(_ point: [Double], _ weight: [Double]) { // e.g.
print(point, weight)
}

func someFunction2(_ point: [[Double]], _ weight: [Double]) { // e.g.
for i in 0 ..< point.count {
print(point[i], weight)
}
}
``````

How can I avoid the duplication of `someFunction1` if the only thing that changes is the definition of the third argument?

PS: Forgot to mention that `someFunction1` does not use the other properties of `Element1` or `Element2`; only the point and weight properties.

Thank you,
Ricardo

I note that your point properties aren't the same, the first is an array of arrays of Double, and the second is an simple array of Double. Is that intentional?

Yes, that was intentional. That is the reason why I need to duplicate `someFunction1` (because it seems that I cannot use a protocol). Any ideas about how to avoid the duplication?

Thank you,
Ricardo

Maybe something like

``````func theFunction(_ arg1: Int, _ arg2: Int, _ element: Any) {
if element is Element1 {
//some code
} else if element is Element2 {
//some other code
}
}
``````

This does have the disadvantage of needing to be extra vigilant about handling bad inputs, so maybe not worth it, but it might work.

Why is it that you cannot use a protocol? It would seem an ideal way to solve your issue

I also thought protocol is an ideal way to solve that problem. For instance

``````protocol WeightPoint {
var points: [[Double]] { get }
var weight: [Double] { get }
}
``````

In that particular case, the type of “point” is different, but they are easy to differentiate. You could have:

``````struct Element1: WeightPoint {
var sky: Int
var bird: [Int]
var points: [[Double]]
var weight: [Double]
}

struct Element2: WeightPoint {
var ocean: Int
var whale: [Int]
var point: [Double]
var weight: [Double]
// adding computed property just to do have an attribute of the same type; if you can’t change the definition, you could try an extension method
var points: [[Double]] {
return [point]
}
}
``````

Then you write your function as usual:

``````func someFunction1(_ arg1: Int, _ arg2: Int, _ element: WeightPoint) {
// TODO
someFunction2(element)
// TODO
}
func someFunction2(_ weightPoint: WeightPoint) {
// TODO
}``````

Davide, I thought that I could not use a protocol because the type of `point` happens to be distinct in both structs. However, as suggested by Ataias, the second struct can be modified to include a dummy variable called `points` so that both structs share the same variable name and type.

I will go ahead and test Hacksaw's and Ataias' approach and see which one fits better in my code. Thank you for all the ideas.

Ricardo

It seems like the only reason why your functions aren't generic is because `point` can be either `[Double]` or `[[Double]]` depending on its enclosing type.

One potential solution is to create a wrapping enum that's able to represent both `Array` and `Array<Array>>`. I've done something similar in one of my project.

Remember that “protocols are not bags of syntax”. You want to put the semantics you care about in the protocol.
To me it looks like the semantics you care about in this case are not the properties, but `someFunction1`. If you put that as the requirement you can have each type define it’s own and then have a single `someFunction2`