Найдите лучшие 10 пунктов в Словаре JSON, основанном на Инт - PullRequest
0 голосов
/ 20 октября 2018

Я собираюсь вытащить 10 лучших экземпляров словаря JSON, в основе которого лежат самые высокие значения Int.

Так что для примера, который я показываю, я ищу 10 лучших фильмов по рейтингу в зависимости от их популярности.Я разместил пример словаря ниже.

Часть словаря:

{
"cast": [
{
  "id": 201,
  "character": "Praetor Shinzon",
  "original_title": "Star Trek: Nemesis",
  "overview": "En route to the honeymoon of William Riker to Deanna Troi on her home planet of Betazed, Captain Jean-Luc Picard and the crew of the U.S.S. Enterprise receives word from Starfleet that a coup has resulted in the installation of a new Romulan political leader, Shinzon, who claims to seek peace with the human-backed United Federation of Planets. Once in enemy territory, the captain and his crew make a startling discovery: Shinzon is human, a slave from the Romulan sister planet of Remus, and has a secret, shocking relationship to Picard himself.",
  "vote_count": 643,
  "video": false,
  "media_type": "movie",
  "release_date": "2002-12-13",
  "vote_average": 6.2,
  "title": "Star Trek: Nemesis",
  "popularity": 7.61,
  "original_language": "en",
  "genre_ids": [
    28,
    12,
    878,
    53
  ],
  "backdrop_path": "/1SLR0LqYPU3ahXyPK9RZISjI3B7.jpg",
  "adult": false,
  "poster_path": "/n4TpLWPi062AofIq4kwmaPNBSvA.jpg",
  "credit_id": "52fe4226c3a36847f8007d05"
},
{
  "id": 855,
  "character": "Spec. Lance Twombly",
  "original_title": "Black Hawk Down",
  "overview": "When U.S. Rangers and an elite Delta Force team attempt to kidnap two underlings of a Somali warlord, their Black Hawk helicopters are shot down, and the Americans suffer heavy casualties, facing intense fighting from the militia on the ground.",
  "vote_count": 2540,
  "video": false,
  "media_type": "movie",
  "release_date": "2001-12-28",
  "vote_average": 7.3,
  "title": "Black Hawk Down",
  "popularity": 11.504,
  "original_language": "en",
  "genre_ids": [
    28,
    36,
    10752
  ],
  "backdrop_path": "/7u2p0VxnhVMHzfSnxiwz5iD3EP7.jpg",
  "adult": false,
  "poster_path": "/yUzQ4r3q1Dy0bUAkMvUIwf0rPpR.jpg",
  "credit_id": "52fe4282c3a36847f80248ef"
},

Из этого словаря, какой будет правильный код, используемый для извлечения лучших 10 фильмов на основе их популярностирейтинг?

Вот часть кода:

 struct Cast: Codable {
    let title: String
    let character: String
    let poster_path: String?
    let id: Int
    let popularity: Double?
}

var filmCredits = [Cast]()

Первая проблема, с которой я сталкиваюсь, это когда я использую return 10, чтобы вернуть 10 результатов:

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return 10
}

Я получаю сообщение об ошибке Thread 1: Fatal error: Index out of range при вызове indexPath в моем cellForItemAt func.

Вот функция JSON Decoder:

func loadFilms() {

    let apiKey = ""
    let url = URL(string: "https://api.themoviedb.org/3/person/\(id)/combined_credits?api_key=\(apiKey)&language=en-US")
    let request = URLRequest(
        url: url! as URL,
        cachePolicy: URLRequest.CachePolicy.reloadIgnoringLocalCacheData,
        timeoutInterval: 10 )

    let session = URLSession (
        configuration: URLSessionConfiguration.default,
        delegate: nil,
        delegateQueue: OperationQueue.main
    )

    let task = session.dataTask(with: request, completionHandler: { (data, response, error) in
        if let data = data {
            do {
                let films = try! JSONDecoder().decode(Credits.self, from: data)
                self.filmCredits = films.cast!
                self.topCollection.reloadData()

            }

        }

        self.topCollection.reloadData()

    })


    task.resume()

}

Больше всего я не уверен, каквытащить только 10 лучших фильмов рейтинга.Буду ли я использовать что-то похожее на filter или map?

Ответы [ 3 ]

0 голосов
/ 20 октября 2018

Прежде всего объявите cast в Credits не обязательно

struct Credits: Decodable {
    let cast: [Cast]
}

Сортируйте массив по убыванию popularity при назначении массиву источника данных

self.filmCredits = films.cast.sorted{($0.popularity ?? 0.0) > $1.popularity ?? 0.0})

Не используйте жесткий код numberOfItemsInSection.Сбой происходит, если массив cast содержит менее 10 элементов.Добавьте условие, что 10 элементов отображаются, если количество элементов превышает 10, в противном случае количество элементов в массиве.

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    let numberOfCredits = filmCredits.count
    return numberOfCredits > 10 ? 10 : numberOfCredits
}

И catch возможная ошибка и перезагрузите представление коллекции на главномнить

if let data = data {
    do {
        let films = try JSONDecoder().decode(Credits.self, from: data)
        self.filmCredits = films.cast.sorted{($0.popularity ?? 0.0) > $1.popularity ?? 0.0})
    } catch{ print(error) }
}
DispatchQueue.main.async {
    self.topCollection.reloadData()
}
0 голосов
/ 20 октября 2018

Вы не можете написать return 10 в методе делегата collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int.Вы не можете быть уверены, что у вас всегда будет ровно 10 результатов.Если у вас меньше 10, ваше приложение вылетает в itemForRowAt.

Примечание: вы упоминаете cellForRowAt, что на UITableView с, но ваш код показывает collectionView, убедитесь, что вы используете правильныйметоды-делегаты.

Затем заполните массив, содержащий информацию о популярности, отсортируйте его в порядке убывания, и вам будет полезно пойти и использовать что-то вроде Sh_Khan , упомянутых:

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
       return min(filmCredits.count,10)
    }
0 голосов
/ 20 октября 2018

Вам нужно

filmCredits.sort{ $0.popularity > $1.popularity}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
   return min(filmCredits.count,10)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...