我可以在一个语句中合并for-in和if-let吗?
for item in array {
if let f = item as? NSDictionary {
result.addObject(newFile(f))
}
}
array
由JSON制作,因此我不知道每个项目是否为NSDictionary
。我得检查一下。
我正在寻找这样的事情:
for item as? NSDictionary in array {
// code
}
像Python或Ruby一样。
答案 0 :(得分:3)
@nickfalk走在正确的轨道上,但我们可以做得更好。不幸的是,他的结果会返回[AnyObject]
,然后你就可以用({I}}调用newFile
。但是没关系,我们可以很容易地完成剩下的工作。
你想要的是部分地图。也就是说,您希望将一个列表的一些(但可能不是全部)元素映射到另一个列表(从AnyObject
到File
,如果可以的话)。因此必须有一些选择规则,以及一些映射规则。可选让我们结合这些。让我们调用执行该f
的函数。然后它的类型是:
f: T->U?
因此,有一些神奇的功能可能会将T
转换为U
。我们想用它来映射。听起来很简单:
extension Array {
func partialMap<U>(f: T->U?) -> [U] {
var result = [U]()
for x in self {
if let u = f(x) {
result.append(u)
}
}
return result
}
}
所以现在我们已经隐藏了所有令人讨厌的突变和var
以及我们不必去看它的地方。我们有一个函数,它从&#34;某些东西&#34;中获取映射函数。到了&#34;也许别的东西&#34;并返回一个&#34;我们可以映射的东西列表。&#34;
现在一切都很好,不可改变,可重复使用:
let result = array.partialMap { ($0 as? NSDictionary).map(newFile) }
哇那里。中间的map
是什么?好吧,as?
会返回NSDictionary?
。当map
是可选项时,如果可选项为None
,则返回None
,否则它会将该函数应用于该值并将其包装在Some
中。所以整个过程需要AnyObject
并返回File?
就像我们想要的那样。一partialMap
我们得到了答案。
答案 1 :(得分:3)
我可能会选择类似的东西:
let result = array.filter() { $0 is NSDictionary }
如果你需要result
成为NSDictionary数组,你可以直接投射它:
let result = array.filter() { $0 is NSDictionary } as [NSDictionary]
答案 2 :(得分:1)
如果您的目标是将NSArray
缩减为仅包含NSDictionary
过滤器的数组,那么这是一个非常强大的工具。创建适当的过滤功能:
func filterForNSDictionary(object: AnyObject) -> Bool{
return object.isKindOfClass(NSDictionary)
}
然后简单地将数组和函数传递给filter
函数
let result = filter(array, filterForNSDictionary)
正如@RobNapier所指出的,上面的解决方案最终会得到类型为[AnyObject]
的结果数组,这当然可以很容易地解决:
let result = filter(array, filterForNSDictionary) as [NSDictionary]
如果你强制数组的类型错误,这可能会被认为是有风险的。 as [NSString]
(例如,9很可能会在你面前爆炸......
Rob的解决方案当然是非常棒的聪明,而@MattGibson提供了完美的速记,同时让我在这个领域成为绝对的初学者。