通过 JSON 排序以查找字符串不同的每个实例

Sort through JSON to find each instance that a string is different

我试图找到字符串 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: 的每个实例都不同,然后获取每个名称并将它们放入一个新数组中?

有几种方法可以遍历您的 Shows 数组及其 Theater 数组以获得完整的姓名列表。获得完整的姓名列表后,您可以获得这些姓名的唯一列表。

这是一种方法:

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

让我们把它分开来更好地解释发生了什么。

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

shows.map 遍历 shows 中的每个 Shows。内部 map 依次迭代每个 Shows 中的每个 Theatre,返回其 name。所以内部 map 给出了一个名称数组。第一个 map 导致名称数组的数组。 reduce 将这些名称数组合并为一个名称数组,留下 allNames 一个包含每个名称的数组。

使用 Array(Set(allNames)) 首先创建一组唯一的名称,然后从该组创建一个数组。

如果您希望最终结果按字母顺序排序,则在末尾添加 .sorted()

如果您需要保留原始顺序,您可以使用 NSOrderedSet 并删除任何使用 sorted

let names = NSOrderedSet(array: shows.map { [=12=].showtimes.map { [=12=].theatre.name }}.reduce([]) { [=12=] +  }).array as! [String]