Swift 4过滤json数组到子数组

时间:2018-01-22 14:42:06

标签: arrays swift filter

我收到了这段代码:

let arrData = [["id": "1",
                        "name": "Apple",
                        "category": "Fruit"],
                       ["id": "2",
                        "name": "Pie",
                        "category": "Fruit"],
                       ["id": "3",
                        "name": "Tomato",
                        "category": "Vegetable"]]

        let categorieNames = Array(Set(arrData.map({$0["category"]!})))
        var arrResult:[[String]] = []
        for i in 0..<categorieNames.count {

            let categories = arrData.filter({$0["category"] == categorieNames[i]}).map({$0["name"]!})
            arrResult.append(categories)
        }
        print("result : \(arrResult)")

它与Array完美配合。 但现在我从json获取数据:

[{"id":"1",
  "name":"Apple",
  "category":"Fruits"},
{"id":"2",
 "name":"Pie",
 "category":"Fruits"},
{"id":"3",
 "name":"Tomato",
 "category":"Vegetable"}]

这是我的结构和我的解码功能:

struct MarketStruct : Decodable {
    let id                    : Int?
    let name                  : String?
    let category              : String?
}



  class MarketsCollectionViewController: UICollectionViewController, NetworkDelegate {

    var myMarkets : [MarketStruct]?
    var categorieNames : [Any] = []
    var categorieArray:[[String]] = []


    func didFinish(result: Data) {
        do {
            self.myMarkets  =  try JSONDecoder().decode([MarketStruct].self, from: result)
                categorieNames = Array(Set(myMarkets!.map({ ["category": $0] })))
            for i in 0..<categorieNames.count {
                let categories = myMarkets!.filter({$0["category"] == categorieNames[i]}).map({["name": $0]!})
                categorieArray.append(categories)
            }
        } catch let jsonErr {
            print("Error:", jsonErr)
        }
                self.myCollectionView.reloadData()
    }

我在过滤器部分出错了: 类型'MarketStruct'没有下标成员

我必须更改上面的数组代码是否适用于我的JSON数组?

感谢您的帮助。

编辑我当前的代码:

 self.myMarkets = try JSONDecoder().decode([MarketStruct].self, from: result)
        categorieNames = Array(Set(myMarkets.map({$0.category })))

            for i in 0..<categorieNames.count {
                    let categories = myMarkets!.filter({$0.category == categorieNames[i]}).map({$0.name})
                    categorieArray.append(categories as! [String])
        }

        } catch let jsonErr {
            print("Error:", jsonErr)
        }
        self.myCollectionView.reloadData()

它编译错误:命令因信号失败:分段错误:11

如果我评论 categorieNames = Array(设置(myMarkets.map({$ 0.category}))),则编译时没有错误

2 个答案:

答案 0 :(得分:1)

代码中存在很多问题

  • 在JSON中,AVAudioMixerNode的类型为id而非String
  • 结构中的成员应该是非可选的。
  • Int数组应该是特定的categorieNames,而不是未指定的[String]
  • 在过滤行中按点表示法访问类别,而不是键订阅(错误1)
  • 而不是将[Any]声明为可选,将其初始化为空数组(错误2)
  • 不要使用丑陋的基于索引的for循环,使用快速枚举(不是真正的问题)

为什么要将myMarkets映射到一组词典?

myMarkets

答案 1 :(得分:1)

您收到编译器错误,因为category属性是可选的,因此不符合Hashable

Set要求所有元素都符合这一要求。

解决这个问题的一种方法是使用flatMap而不是map,它具有过滤掉nil值的附加功能。

categorieNames = Array(Set(myMarkets.flatMap({$0.category })))