2015-04-21 12 views
5

Próbuję zbudować funkcję ze swiftem, który zmapuje tablicę, podzieli każdą wartość w tablicy na 3, a następnie wypluje nową tablicę. To, co mam tak daleko:Jak poprawnie sformatować tę funkcję Swift, aby odwzorować tablicę?

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]) 

Gdzie T i U są oryginalne tablicą, a nowa tablica zwrócone są odpowiednio, i to zrobić za pomocą rodzajowych.

Jestem pewien, że to nie jest napisane poprawnie, utknąłem w kwestii właściwej składni. Na przykład, ponieważ zwracana tablica jest reprezentowana przez ogólny [U], zakładam, że muszę go użyć gdzieś w zwracanej tablicy, nie wiem gdzie.

+0

Jeśli to tylko matematyka dlaczego nie można po prostu użyć Int lub Double? –

Odpowiedz

7

Podczas pisania funkcji ogólnej czasami łatwiej jest podejść do niej w 3 krokach: najpierw napisz kod autonomiczny, używając określonego typu. Następnie wpisz kod jako funkcję, nadal z określonym typem. Na koniec zmień funkcję na ogólną.

Pierwsza część podzielenie tablicę przez 3 może być wykonane w następujący sposób:

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) 

Uwaga zamknięcie podać pomiędzy { } to operacja, która zostanie przyłożona do każdej elementu tablicy . $0 reprezentuje element, a dzielisz go przez 3. Można również napisać go jako a.map { i in i/3 }.

Aby umieścić to na własnej funkcji:

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

Nie trzeba zadeklarować nową tablicę - map stworzy dla Ciebie. Możesz wtedy zwrócić to bezpośrednio (możesz przypisać go do tymczasowego, jeśli chcesz, ale to nie jest konieczne).

Wreszcie, jeśli chcemy, aby było rodzajowe, start dodając zastępczy:

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

Uwaga, istnieje tylko potrzeba jednego zastępczego, T, bo wracają dokładnie ten sam typ jesteś przekazany w

... Poza tym nie będzie kompilować, ponieważ kompilator nie wie, że T gwarantuje dostarczenie dwóch ważnych rzeczy:. zdolność do podziału (operator /) oraz zdolność do tworzenia nowych T od liczby całkowitej literały (tj. stworzyć T o wartości 3, aby podzielić według). W przeciwnym razie, jeśli przekażemy tablicę łańcuchów lub tablicę tablic?

Aby to zrobić, musimy "ograniczyć" T, więc nasza funkcja będzie akceptować tylko te typy argumentów, które zapewniają te funkcje. Jeden taki protokół możemy użyć, aby ograniczyć T jest IntegerType, który ma zagwarantować te funkcje (jak również kilka innych te, jak +, * 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] 
Powiązane problemy