1

I'm parsing JSON data and iterating through the results and everything is just fine. But i needed a way to control the number of iteration within the loop. For instance to get the first 10 results only.

Here im parsing JSON weather data status icons. I just want to get the first 10 results and append them to the array.

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)
     }
  }
2
  • 1
    Do you mean arrayList[0..<10]? Commented Feb 23, 2016 at 17:45
  • @Cristik yes something like that but i just need the proper syntax. Or hey maybe i can add a var i=0 and when it reaches <10 stop the loop. Commented Feb 23, 2016 at 17:57

2 Answers 2

1

There are quite a few ways you can do this.

As you suggest, you can manually control your loop to run for the first n elements:

if let list = arrayList["weather"] as? [[String : AnyObject]] {

   for i in 0 ..< 10 {
      let arrayList = list[i]
      // Do stuff with arrayList
   }
}

You can use the ArraySlice syntax that Cristik suggested in his comment if you know the length of the array is at least 10:

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
   }
}

The prefix(_:) method might be clearest, though. This method has the advantage that if the argument you supply is greater than the array's length, it will return the elements you do have without throwing an error:

if let list = arrayList["weather"] as? [[String : AnyObject]] {
   let firstTenResults = list.prefix(10)
   for arrayList in firstTenResults {
      // Do stuff with arrayList
   }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks @Ronald Martin it worked. I used list.prefixUpTo(Int)
1

Here's a very Swiftish solution:

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

Basically you're reducing over the weather array by using a pair consisting of a counter and the result array. If the counter exceeds 10, or you can't download the image, you simply move to the next item by returning the accumulated value, otherwise you increment the counter and append the downloaded image.

Note that you get an optional, as the first cast might fail. However I'm sure you won't have a problem with this, considering from the posted code that you know how to handle optionals :)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.