Сортировка по JSON, чтобы найти каждый экземпляр, что строка отличается

Я пытаюсь найти каждый экземпляр строки name: быть другим.

Что касается примера JSON ниже, я хочу вытащить Alamo Draft House Lamar и Alamo Draft House Ritz и поместить их в массив.

JSON:

[{
"tmsId": "MV011110340000",
"rootId": "15444050",
"subType": "Feature Film",
"title": "Bohemian Rhapsody",
"releaseYear": 2018,
"releaseDate": "2018-11-02",
"titleLang": "en",
"descriptionLang": "en",
"entityType": "Movie",
"genres": ["Biography", "Historical drama", "Music"],
"longDescription": "Singer Freddie Mercury, guitarist Brian May, drummer Roger Taylor and bass guitarist John Deacon take the music world by storm when they form the rock 'n' roll band Queen in 1970. Surrounded by darker influences, Mercury decides to leave Queen years later to pursue a solo career. Diagnosed with AIDS in the 1980s, the flamboyant frontman reunites with the group for Live Aid -- leading the band in one of the greatest performances in rock history.",
"shortDescription": "Singer Freddie Mercury of Queen battles personal demons after taking the music world by storm.",
"topCast": ["Rami Malek", "Lucy Boynton", "Gwilym Lee"],
"directors": ["Bryan Singer"],
"officialUrl": "https://www.foxmovies.com/movies/bohemian-rhapsody",
"ratings": [{
    "body": "Motion Picture Association of America",
    "code": "PG-13"
}],
"advisories": ["Adult Language", "Adult Situations"],
"runTime": "PT02H15M",
"preferredImage": {
    "width": "240",
    "height": "360",
    "uri": "assets/p15444050_v_v5_as.jpg",
    "category": "VOD Art",
    "text": "yes",
    "primary": "true"
},
"showtimes": [{
    {
    "theatre": {
        "id": "9489",
        "name": "Alamo Drafthouse at the Ritz"
    },
    "dateTime": "2018-11-10T19:15",
    "barg": false,
    "ticketURI": "http://www.fandango.com/tms.asp?t=AAUQP&m=185586&d=2018-11-10"
}, {
    "theatre": {
        "id": "9489",
        "name": "Alamo Drafthouse at the Ritz"
    },
    "dateTime": "2018-11-10T22:30",
    "barg": false,
    "ticketURI": "http://www.fandango.com/tms.asp?t=AAUQP&m=185586&d=2018-11-10"
}, {
    "theatre": {
        "id": "5084",
        "name": "Alamo Drafthouse South Lamar"
    },
    "dateTime": "2018-11-10T12:00",
    "barg": false,
    "ticketURI": "http://www.fandango.com/tms.asp?t=AATHS&m=185586&d=2018-11-10"
}, {
    "theatre": {
        "id": "5084",
        "name": "Alamo Drafthouse South Lamar"
    },
    "dateTime": "2018-11-10T15:40",
    "barg": false,
    "ticketURI": "http://www.fandango.com/tms.asp?t=AATHS&m=185586&d=2018-11-10"
},
}]
}]

Вот мой код API:

var shows = [Shows]()

struct Shows: Codable {
    let showtimes: [Showtimes]

    struct Showtimes: Codable {
    let theatre: Theater

        struct Theater: Codable {
            let id: String
            let name: String
        }

    }
}

func loadShowtimes() {

    let apiKey = ""
    let today = "2018-11-10"
    let zip = "78701"
    let filmId = "MV011110340000"
    let radius = "15"
    let url = URL(string: "http://data.tmsapi.com/v1.1/movies/\(filmId)/showings?startDate=\(today)&numDays=5&zip=\(zip)&radius=\(radius)&api_key=\(apiKey)")
    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 shows = try! JSONDecoder().decode([Shows].self, from: data)
                self.shows = shows

            }
        }
    })

    task.resume()

}

Как бы я подошел к сортировке массива и нахождению каждого экземпляра name: отличаться, затем взять каждое имя и поместить их в новый массив?

1 ответ

Решение

Есть несколько способов перебора вашего массива Shows и их массив Theater чтобы получить полный список имен. Если у вас есть полный список имен, вы можете получить уникальный список этих имен.

Вот один из подходов:

let names = Array(Set(shows.map { $0.showtimes.map { $0.theatre.name }}.reduce([]) { $0 + $1 }))

Давайте разберем это, чтобы лучше объяснить, что происходит.

let allNames = shows.map { $0.showtimes.map { $0.theatre.name }}.reduce([]) { $0 + $1 }
let uniqueNames = Array(Set(allNames))

shows.map перебирает каждый Shows в shows, Внутренний map в свою очередь повторяет каждый Theatre в каждом из тех Shows возвращая его name, Так что внутренний map дает массив имен. Первый map приводит к массиву массивов имен. reduce объединяет эти массивы имен в единый массив имен, оставляя allNames с одним массивом, содержащим каждое имя.

Использование Array(Set(allNames)) сначала создает уникальный набор имен, а затем создает массив из этого набора.

Если вы хотите, чтобы окончательный результат сортировался по алфавиту, добавьте .sorted() к концу.

Если вам нужно сохранить первоначальный заказ, вы можете использовать NSOrderedSet и удалите любое использование sorted,

let names = NSOrderedSet(array: shows.map { $0.showtimes.map { $0.theatre.name }}.reduce([]) { $0 + $1 }).array as! [String]
Другие вопросы по тегам