我对词典有一个扩展,添加了map
,flatMap
和filter
。在大多数情况下它是可用的,但我对如何指定转换和谓词函数的参数感到不满。
首先,扩展本身:
extension Dictionary {
init<S:SequenceType where S.Generator.Element == Element>(elements: S) {
self.init()
for element in elements {
self[element.0] = element.1
}
}
func filter(@noescape predicate:(Key, Value) throws -> Bool ) rethrows -> [Key:Value] {
return [Key:Value](elements:try lazy.filter({
return try predicate($0.0, $0.1)
}))
}
}
现在,由于predicate
参数被声明为predicate:(Key, Value)
,我希望以下内容能够正常工作:
["a":1, "b":2].filter { $0 == "a" }
然而,我必须实际使用:
["a":1, "b":2].filter { $0.0 == "a" }
这有点令人困惑,因为声明意味着当谓词实际上作为单个元组参数传递时,有两个参数,而不是2个值。
显然,我可以将过滤器函数声明更改为单个参数(predicate:(Element)
),但我真的更喜欢它采用两个明确单独的参数。
关于如何实际获取函数以获取两个参数的任何想法?
答案 0 :(得分:2)
当您使用没有类型声明的闭包时,编译器必须推断出类型。如果您只使用$0
而不是$1
,则编译器会认为您只使用一个参数声明了闭包。
此闭包无法与您的filter
函数匹配。简单修复:
let result = ["a":1, "b":2].filter { (k, _) in k == "a" }
现在还要记住,元组可以传递给函数并自动匹配参数:
func sum(x: Int, _ y: Int) -> Int {
return x + y
}
let params = (1, 1)
sum(params)
然后可以通过类型推断来解释["a":1, "b":2].filter { $0.0 == "a" }
的行为。有两种可能性,编译器只是选择了错误的一种,因为它认为你只想要一个带有一个参数的闭包 - 而且这个参数必须是一个元组。
答案 1 :(得分:0)
您可以添加比较功能,以便比较Dictionary.Element
和Key
func ==<Key: Hashable,Value>(lhs:Dictionary<Key,Value>.Element, rhs:Key) -> Bool {
return lhs.0 == rhs
}