我正在解析JSON数据并迭代结果,一切都很好。但我需要一种方法来控制循环内的迭代次数。例如,仅获得前10个结果。
这里我解析JSON天气数据状态图标。我只想获得前10个结果并将它们附加到数组中。
if let list = arrayList["weather"] as? [[String : AnyObject]]{
for arrayList in list{
if let iconString = arrayList["icon"] as? String{
if let url = NSURL(string: "http://openweathermap.org/img/w/\(iconString).png"){
let iconImgData = NSData(contentsOfURL: url)
let image = UIImage(data: iconImgData!)
self.forcastImg.append(image!) self.forcastView.reloadData()
}
}
//print(list)
}
}
答案 0 :(得分:1)
这是一个非常迅捷的解决方案:
let first10Images = (arrayList["weather"] as? [[String : AnyObject]])?.reduce((0, [UIImage]())) {
guard $0.0.0 < 10,
let iconString = $0.1["icon"] as? String,
url = NSURL(string: "http://openweathermap.org/img/w/\(iconString).png"),
iconImgData = NSData(contentsOfURL: url),
image = UIImage(data: iconImgData)
else {
return $0.0
}
return ($0.0.0 + 1, $0.0.1 + [image])
}.1
基本上,你通过使用一个由计数器和结果数组组成的对来减少weather
数组。如果计数器超过10,或者您无法下载图像,只需返回累计值即可移至下一项,否则您将增加计数器并附加下载的图像。
请注意,您获得了一个可选项,因为第一次投射可能会失败。但是我相信你不会有这个问题,考虑到你知道如何处理选项的已发布代码:)
答案 1 :(得分:1)
有很多方法可以做到这一点。
如您所知,您可以手动控制循环以运行第一个 n 元素:
if let list = arrayList["weather"] as? [[String : AnyObject]] {
for i in 0 ..< 10 {
let arrayList = list[i]
// Do stuff with arrayList
}
}
如果你知道阵列的长度至少为10,你可以使用Cristik在评论中建议的ArraySlice syntax:
if let list = arrayList["weather"] as? [[String : AnyObject]] where list.count > 10 {
let firstTenResults = list[0 ..< 10]
for arrayList in firstTenResults {
// Do stuff with arrayList
}
}
prefix(_:)
方法可能最清晰。这种方法的优点是,如果你提供的参数大于数组的长度,它将返回你所拥有的元素而不会抛出错误:
if let list = arrayList["weather"] as? [[String : AnyObject]] {
let firstTenResults = list.prefix(10)
for arrayList in firstTenResults {
// Do stuff with arrayList
}
}