¿Cómo formatearé correctamente esta function Swift para asignar una matriz?

Estoy tratando de build una function con swift que mapeará una matriz, dividirá cada valor en la matriz por 3 y luego escupirá una nueva matriz. Esto es lo que tengo hasta ahora:

func divideby3Map<T, U>(y: [T], z: T -> U) -> [U] { let array = [int]() let divideby3Array = array.map { [y] / 3 } return dividedby3Array } divideby3Map([1,2,3,4,5]) 

Donde T y U son la matriz original, y la nueva matriz se devuelve respectivamente, y se hace usando generics.

Estoy seguro de que esto no está escrito correctamente, estoy atrapado en términos de la syntax correcta. Por ejemplo, dado que la matriz que se devuelve está representada por el genérico [U] , supongo que debo usarla en algún lugar de la matriz que se está devolviendo, aunque no estoy seguro de dónde.

Al escribir una function genérica, a veces es más fácil abordarla en 3 pasos: primero escriba el código independiente usando un tipo específico. Luego escriba el código como una function, aún con un tipo específico. Finalmente, cambie la function para ser genérica.

La primera parte, dividiendo una matriz por 3, se puede hacer así:

 let a = [1,2,3,4,5] // map is run on the array of integers, and returns a new // array with the operation performed on each element in a: let b = a.map { $0 / 3 } // so b will be [0,0,1,1,1] // (don't forget, integer division truncates) 

Tenga en count que el cierre que proporciona entre { } es una operación que se aplicará a cada elemento de la matriz. $0 representa el elemento, y lo divide por 3. También podría escribirlo como a.map { i in i / 3 } .

Para poner esto en su propia function:

 func divideby3Map(source: [Int]) -> [Int] { return source.map { $0 / 3 } } 

No es necesario declarar una matriz nueva: el map creará una para usted. Luego puede devolverlo directamente (puede asignarlo temporalmente si lo prefiere, pero eso no es realmente necesario).

Finalmente, si quiere que sea genérico, comience agregando un marcador de position:

 func divideby3Map<T>(source: [T]) -> [T] { return source.map { $0 / 3 } } 

Tenga en count que solo se necesita un marcador de position, T , porque devuelve exactamente el mismo tipo en el que se pasa.

Excepto … esto no se comstackrá, ya que el comstackdor no sabe que T está garantizado para proporcionar dos elementos críticos: la capacidad de dividir (a / operator) y la capacidad de crear nuevos T partir de literales integers (es decir, para crear un T con valor 3 para dividir por). De lo contrario, ¿qué pasaría si pasáramos una matriz de cadenas o una matriz de matrices?

Para hacer esto, necesitamos "restringir" T para que nuestra function solo acepte como types de arguments que proporcionan estas características. Uno de esos protocolos que podemos usar para restringir T es IntegerType , que garantiza estas características (así como algunas otras como + , * etc):

 func divideby3Map<T: IntegerType>(source: [T]) -> [T] { return source.map { $0 / 3 } } divideby3Map(a) // returns [0,0,1,1,1] let smallInts: [UInt8] = [3,6,9] divideby3Map(smallInts) // returns [1,2,3]