使用swift 3从json数组中选择特定元素

Posted

技术标签:

【中文标题】使用swift 3从json数组中选择特定元素【英文标题】:Select specific elements from json array using swift 3 【发布时间】:2017-01-20 13:21:29 【问题描述】:

我正在显示 json 数组中的一些数据,但它正在打印整个数组,创建的正是 json 数组长度的单元格数量。我想显示具体的数据,那我该怎么做呢?

这是我的 json 链接: https://jsonplaceholder.typicode.com/photos

我想显示albumId = 1的那些数据的标题

这是我的代码:

class PhotosByAlbumViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout 

@IBOutlet weak var myCollectionView: UICollectionView!

var albumId:Int = 1 // It is my album ID
var allImages: [Any] = []
let urlForData = URL(string: "https://jsonplaceholder.typicode.com/photos")

override func viewDidLoad() 
    super.viewDidLoad()


    callToFetchJson()



override func didReceiveMemoryWarning() 
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.


func callToFetchJson() 

    let request = URLRequest(url: urlForData!)
    URLSession.shared.dataTask(with: request)  (data, response, error) in
        if data == nil && error != nil 
            print("No Data")
        
        else if data != nil && error != nil 
            print("Error")
        
        else 
            DispatchQueue.main.sync 
                self.decodingJson(data!)
            

        
        .resume()



func decodingJson(_ data: Data ) 
    do 
        let allImage = data
        allImages = try JSONSerialization.jsonObject(with: allImage, options: JSONSerialization.ReadingOptions.allowFragments) as! [Any]
        self.myCollectionView.reloadData()
    
    catch 

    



func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 

    return CGSize(width: 150 , height: 180)



func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
    return self.allImages.count


func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 

    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "albumPhotoCell", for: indexPath as IndexPath) as! albumPhotoCollectionViewCell

    let aImg:[String: AnyObject] = allImages[indexPath.item] as! [String: AnyObject]
    cell.imageDescription.text = (aImg["title"] as! String)
    return cell


func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) 
    // handle tap events
    print("You selected cell #\(indexPath.item)!")



【问题讨论】:

我查看了您的 JSON 链接,加载大约需要 10 秒。您能否将该 JSON 的一小部分样本移到问题中,而不是提供一个可能在几天后失效的链接? @akousmata 我认为您的 Internet 连接速度很慢。改善男人 它不会死的。我发现这个链接是假的 json api。这些链接可用于使用 json 数据测试任何产品。 【参考方案1】:

您需要在反序列化后过滤您的数组。这应该足够了:

func decodingJson(_ data: Data ) 
    do 
        let allImage = data
        allImages = try JSONSerialization.jsonObject(with: allImage, options: JSONSerialization.ReadingOptions.allowFragments) as! [Any]
        allImages = allImages.filter  $0["albumId"] == albumId 
        self.myCollectionView.reloadData()
    
    catch 

    


添加此行后,只有 "albumId" : 1 的元素应包含在您的 allImages 数组中。

【讨论】:

我找到了我的解决方案。我可以在 url 中执行此操作: urlForData(URL: "jsonplaceholder.typicode.com/photos?albumId=(albumId)") in viewdidload 顺便谢谢你的回答 没问题!如果我知道你的 API 支持这样的查询,我会建议它。一般来说,最好将尽可能多的业务逻辑/繁重的任务卸载到后端。 你是对的。首先获取所有 5000 个结果然后将它们过滤到 50 是一项繁重的任务,而不是我们尝试仅获取 50 个结果。 好吧,如果您或您的团队开发后端,您还可以实施分页 - 及时albumId=1 的结果数量也可能增长。

以上是关于使用swift 3从json数组中选择特定元素的主要内容,如果未能解决你的问题,请参考以下文章

解析 json 数组在 swift 中返回空元素

使用 SwiftyJSON 选择字符串数组

在 knockout.js 视图模型(数组)中存储特定元素

Swift flatMap:如何从数组中仅删除元组中特定元素为零的元组?

选择 json 数组包含特定元素的行

如何使用 Angular JS 排序和选择 json 数组中的前 5 个元素