【发布时间】:2014-09-04 21:52:19
【问题描述】:
作为 Swift 新手,作为练习练习,我正在尝试编写一个等效于 underscore.js'_.each 的 Swift:
_.each({foo: true, bar: false}, function(value, key) {...}
_.each([true, false], function(value, key) {...}
但事实证明这很困难,因为 enumerate(collection) 会为字典和数组返回不同类型的结果:
for (indexInt, (key, value)) enumerate(["foo": true]) {...}
for (key, value) enumerate([true]) {...}
如何处理这两种不同的返回类型而不明确检查泛型集合的Array 或Dictionary 类?
返回类型检查将失败,因为以下两个示例应区别对待,但从 enumerate() 返回等效类型:
for (indexInt, (key, value)) enumerate(["foo": true]) {...}
for (indexInt, (key, value)) enumerate([("foo", true")]) {...}
另外,FWIW,$.swift 似乎在这方面下注:
https://github.com/ankurp/Dollar.swift/blob/master/Dollar/Dollar/Dollar.swift#L193-L217
编辑:格式化。还有。。
一个损坏的通用实现
func each<C: Collection>(collection: C, fn: (Any, Any) -> ()) -> C {
// On next line... Error: Tuple pattern cannot match values of the non-tuple type 'C.GeneratorType.Element'
for (_, (k, v)) in enumerate(collection) {
if let innerV = collection[innerK] {
fn(innerV, k)
}
}
return collection
}
var ret = each(["foo":true, "bar":false]) { println("Key \($1), Value:\($0)") }
一个有效的字典实现
func eachDictionary<K,V>(collection: Dictionary<K, V>, fn: (V, K) -> ()) -> Dictionary<K, V> {
for (_, (k, v)) in enumerate(collection) {
fn(v, k)
}
return collection
}
var retDictionary = eachDictionary(["foo":true, "bar":false]) { println("Key \($1), Value:\($0)") }
一个有效的数组实现
func each<V>(collection: V[], fn: (V, Int) -> ()) -> V[] {
for (k, v) in enumerate(collection) {
fn(v, k)
}
return collection
}
var retArray = each([true, false]) { println("Key \($1), Value:\($0)") }
编辑 2:更新了使用重载的示例。 我特别想问是否有一种通用的 Collection Protocol 方式来实现这一点,而不需要对每个 Collection 类型进行一次性处理?
编辑 3:我尝试了以下操作(我必须在空数组的情况下添加更多类型,这样它就不会抱怨回调的参数不可打印)但是...
- 现在字典失败了(传递
(K,V)作为值) -
[(V1,V2)]案例失败 - 我非常想找到一种方法来使用泛型
(K, V)而不是(Any, Any)
代码:
func each<C: Collection>(collection: C, fn: (Any, Any) -> ()) -> C {
for (k, v) in enumerate(collection) {
if let (key, value) = v as? (Any, Any) {
fn(value, key)
} else {
fn(v, k)
}
}
return collection
}
var ret = each(["foo":true, "bar":false]) { println("1: Key \($1), Value:\($0)") }
var arr : String[] = []
var retOne = each(arr) { println("2: Key \($1), Value:\($0)") }
var retTwo = each([true, false]) { println("3: Key \($1), Value:\($0)") }
【问题讨论】:
标签: arrays generics dictionary swift each