2015-04-21 21 views
5

Bir diziyi eşleştirecek, dizideki her değeri 3'e bölen ve ardından yeni bir dizi tüküren hızlı bir işlev oluşturmaya çalışıyorum. Bu defa ne var: T ve U orijinal dizi ve yeni dizisi sırasıyla iade edilen ve eşdeğer ilaç kullanımıyla bitti vardırDiziyi eşlemek için bu Swift işlevini düzgün şekilde nasıl biçimlendiririm?

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

.

Bunun düzgün yazılmadığından emin olduğumdan, doğru sözdizimi açısından sıkışmış durumdayım. Örneğin, döndürülen dizi jenerik [U] tarafından temsil edildiğinden, döndürdüğünüz dizide bir yere kullanmam gerektiğini varsayardım, yine de emin değilim.

+0

: Biz T sınırlamak için kullanabilirsiniz böyle bir protokol (+, * vb gibi yanı sıra bazı diğer olanlar) bu özellikleri garanti etmez, hangi IntegerType olduğunu ya da çift? –

cevap

7

Genel bir işlev yazarken bazen 3 adımda yaklaşmak daha kolaydır: önce kodu tek başına belirli bir tür kullanarak yazın. Ardından kodu belirli bir türle hala bir işlev olarak yazın. Son olarak, genel olarak işlevini değiştirin.

birinci bölüm 3 ile bir dizi bölme, böyle yapılabilir:

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) 

Not { } arasında sağlanan kapatma dizisi her elemanı uygulanacak bir işlemdir . $0 öğeyi temsil eder ve 3 ile bölüştürür. Ayrıca a.map { i in i/3 } olarak da yazabilirsiniz.

kendi fonksiyonuna içine koymak için:

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

gerek yok taze diziyi bildirmek için - map sizin için bir tane yaratacaktır. Daha sonra bunu doğrudan geri alabilirsiniz (tercih ederseniz geçici olarak atayabilirsiniz, ancak bu gerçekten gerekli değildir). Eğer, bu jenerik hale bir yer tutucu ekleyerek başlamak istiyorsanız

Son olarak:

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

Not Eğer geçirilen aynı tip dönüyor çünkü bir yer tutucu, T için sadece bir ihtiyaç, orada içinde

bu derleyici T iki kritik şeyler sunmak için garanti edildiğini bilmediği için, derlemek olmaz ... hariç

. tamsayı yeni T oluşturma olanağı (a / operatörü) bölmek için yeteneği ve hazırlıklar (yanioluşturmak için)3 değeri ile bölmek için). Aksi takdirde, bir dizi dizeden veya dizilerden oluşan bir diziden geçersek ne olur?

Bunu yapmak için, T'u "sınırlamaya" ihtiyacımız var, bu nedenle işlevimiz yalnızca bu özellikleri sağlayan bağımsız değişken türleri olarak kabul edilecektir. Eğer sadece Int kullanmayın neden sadece matematik ise

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] 
İlgili konular