2016-04-11 19 views
1

Array uzantısı olarak bir zip işlevi uygulamaya çalışıyorum ve bunun gibi kullanılmasını istiyorum. Bu:swift - '[Int]' türünün beklenen argüman türüne dönüştürülemez '[_]'

extension Array { 
    public func zip<T,U>(vals: [U]) -> [T:U] { 

     var dict: [T:U] = Dictionary() 

     for (i,key) in self.enumerate() { 
      if let k = key as? T { 
       dict[k] = vals[i] 
      } 
     } 

     return dict 
    } 
} 

let myKeys = ["a","b","c"] 
let myVars = [1,2,3] 
myKeys.zip(myVars) // ERROR: Cannot convert value of type '[Int]' to expected argument type '[_]' 

son satırda ben tamamen anlamıyorum bir hata alıyorum:

let myKeys = ["a","b","c"] 
let myVars = [1,2,3] 
myKeys.zip(myVars) // ["a":1,"b":2,"c":3] 

İşte benim girişimidir. Bunu [Int] geçirdiğimi ve [_] beklediğimi anladım. Ama burada sadece genel bir yer tutucu değil mi? Neden [Int] almaktan şikayet ediyor? Bir sınıf fonksiyonu olarak zip uygulamak durumunda

Ayrıca

, hiç sorunları vardır: Bu konuda

class func zip<T,U>(keys keys: [T], vals: [U]) -> [T:U] { 

    var dict: [T:U] = Dictionary() 

    for (i,key) in keys.enumerate() { 
     dict[key] = vals[i] 
    } 

    return dict 
} 

zip(keys: myKeys,vals: myVals) // ["a":1,"b":2,"c":3] 

Herhangi bir düşünce çok takdir!

cevap

2

Array'un zaten ilişkili bir türe sahip olduğunu unutmayın, buna Element adı verilir, dolayısıyla T bildirmesine gerek yoktur. Kodunuzdaki sorun, Element'u tanımsız tür T'a dönüştürememenizdir (T ve dizi öğesi türü arasında bağlantı yoktur).

extension Array where Element: Hashable { 
    public func zip<U>(vals: [U]) -> [Element: U] { 

     var dict: [Element: U] = Dictionary() 

     for (i, key) in self.enumerate() { 
      dict[key] = vals[i] 
     } 

     return dict 
    } 
} 

let myKeys = ["a","b","c"] 
let myVars = [1,2,3] 
let map = myKeys.zip(myVars) 

print(map) 

Ayrıca ben anahtarları için Hashable şartı eklemiş unutmayın.

+0

Teşekkürler @Sulthan! Bu tam olarak amaçlandığı gibi çalışır. – OhNo