如何基于json中的bool值过滤和显示表视图和集合视图值

时间:2019-02-13 06:38:40

标签: ios swift iphone filter

我有的json列表:

 [
     {

         "title": "Languages",
         "name_list": [
             {

                 "title": "Hindi",
                 "locked": true
             },
             {
                 "title": "Hindi1",
                 "locked": true
             },
             {
                 "title": "Hindi2",
                 "locked": false
             },
             {
                 "title": "Hindi3",
                 "locked": true
             },
             {
                 "title": "Hindi4",
                 "locked": false
             }],
     },
     {

         "title": "Subject",
         "name_list": [
             {
                 "title": "Hindi4",
                 "locked": false
             },
             {
                 "title": "Hindi4",
                 "locked": true
             },
             {
                 "title": "Hindi4",
                 "locked": true
             }]
     }    
 ]

我正在使用表视图,并且在表视图内部我具有集合视图。

现在,在表格视图中,我将显示标题。在集合视图中,我将在每个集合视图单元格上显示name_list标题。现在一切正常。

我需要的是,正如您在json中看到的那样,其中有很多锁定的值分别为true和false。

因此,在我的表格视图中,哪个对象的locked == false较少。我需要首先显示该标题。例如。

在我上面的json中,title =主题只有1个lock = false,而title =语言只有2个lock = false。因此,在我的表格视图中,必须先显示主题和语言。

在每个集合视图中相同,哪些对象已锁定= false,需要首先在我的集合视图单元格中显示。

请帮忙。

这是我的表格视图代码:

cellTitleLabel.text = jsonData?["title"] as? String ?? ""

在我的收藏视图中:

if let gamesList = jsonData?["name_list"]  as? [[String: Any]] {
   let Info = nameList[indexPath.item]
   collectionCell.cellTitleLabel.text = Info["title"] as? String ?? ""
}

   var Info: [String: Any]?{
        didSet {

            cellTitleLabel.text = jsonData?["title"] as? String ?? ""
            collectionView.reloadData();

            guard let gamesList = jsonData?["name_list"]  as? [[String: Any]] else {
                return
            }
        }
    }

enter image description here

5 个答案:

答案 0 :(得分:0)

我在json下面使用了这个作为假人

[
    {
        "title": "Languages",
        "name_list": [
            {
                "title": "Sub 1",
                "locked": true
            },
            {
                "title": "Sub 2",
                "locked": true
            },
            {
                "title": "Sub 3",
                "locked": false
            },
            {
                "title": "Sub 4",
                "locked": true
            },
            {
                "title": "Sub 5",
                "locked": false
            }
        ]
    },
    {
        "title": "Subject",
        "name_list": [
            {
                "title": "Sub 6",
                "locked": false
            },
            {
                "title": "Sub 7",
                "locked": false
            },
            {
                "title": "Sub 8",
                "locked": false
            }
        ]
    }
]

此json的模型结构:

public struct TestModel {

    public var nameList : [NameList]
    public var title : String
}

public struct NameList {

    public var locked : Bool
    public var title : String

}

我的json在本地项目中,因此我在func下使用此

func getLocalData(){
    let url = Bundle.main.url(forResource: "testjson", withExtension: "json")!
    do {
        let jsonData = try Data(contentsOf: url)
        let json = try JSONSerialization.jsonObject(with: jsonData) as! [Any]
       self.arrData = self.createDataModel(json)
    }
    catch {
        print(error)
    }
}

Func将json绑定到模型struct

func createDataModel (_ json : [Any]) -> [TestModel] {
    var arr = [TestModel]()

    for adata in json {
        let aDictItems = adata as! [String : Any]
        let aNameListData = aDictItems["name_list"] as! [Any]
        var arrNameList = [NameList]()

        for aName in aNameListData {
            let adictname = aName as! [String : Any]
            arrNameList.append(NameList.init(locked: adictname["locked"] as! Bool, title: adictname["title"] as! String ))
        }

        arr.append(TestModel.init(nameList: arrNameList, title: aDictItems["title"] as! String))

    }
    return arr
}

最后,func将列表分类为锁定计数(false)并返回过滤后的数据。

func filterData (_ searchText : String) -> [TestModel] {
    if searchText == "" { return arrData }

    let s = arrData.sorted { (res1, res2) -> Bool in
        var count1 = 0, count2 = 0
        for r in res1.nameList {
            if !r.locked {
                count1 += 1
            }
        }
        for r in res2.nameList {
            if !r.locked {
                count2 += 1
            }
        }
        return count1 > count2
    }

    let f = s.filter {
        $0.nameList.contains(where: { (aNameRes) -> Bool in
          aNameRes.title.contains(searchText)
        })
    }
    return f
}

  

编辑:显示单元格中的数据

tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
    return filtered.Count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    :
    // filtered[indexPath.row].title // your tableview cell title
    // filtered[indexPath.item].nameList // your collectView Data, Use this array to show data in collectionview
}

注意:您的API json数据和过滤后的数据始终相同。如果搜索栏中没有字符串,则需要使用api原始数据切换过滤后的数据。


如果您的要求有所变化,请告诉我。

答案 1 :(得分:0)

我这里的解决方案是在表视图单元格中创建一个函数,并在cellForRowAt indexPath中使用相应的数组对其进行调用。您只需通过cell. fillCollectionView(array)即可调用该函数。

class ExampleTableViewCell: UITableViewCell {

@IBOutlet weak var exampleCollectionView: UICollectionView!

var array = [[String:Any]]()

func fillCollectionView(with array: [[String:Any]]) {
    self.array = array
    exampleCollectionView()
}

答案 2 :(得分:0)

在这种情况下,如果要首先显示locked == false,则需要重新排列数组字典(按锁定排序)。然后将数据加载到UItableviewUIcollectionview

答案 3 :(得分:0)

只需使用此功能,它将对您有效,而无需创建任何模型。

func sortArr(array : [[String:Any]]) -> [[String:Any]]{
var arr = array
for i in 0...arr.count - 1 {
    var dict = arr[i]
    let name_list = dict["name_list"] as! [[String:Any]]
    let lockedItems = name_list.filter { (item) -> Bool in
        let locked = item["locked"] as! Bool
        if locked == false {
            return true
        }
        return false
    }
    print(lockedItems.count)
    dict["lockedItems"] = lockedItems.count
    arr[i] = dict
}
arr = arr.sorted(by: { (item1, item2) -> Bool in
    let lockedcount1 = item1["lockedItems"] as! Int
    let lockedcount2 = item2["lockedItems"] as! Int
    return lockedcount1 < lockedcount2
})
return arr
}

已编辑

import UIKit
var arr = [
[

"title": "Languages",
"name_list": [
[
"title": "Hindi",
"locked": true
],
[
"title": "Hindi1",
"locked": true
],
[
"title": "Hindi2",
"locked": false
],
[
"title": "Hindi3",
"locked": true
],
[
"title": "Hindi4",
"locked": false
]],
],

[

"title": "Subject",
"name_list": [
[
"title": "Hindi4",
"locked": false
],
[
"title": "Hindi4",
"locked": true
],
[
"title": "Hindi4",
"locked": true
]]
]

]

func sortArr(array : [[String:Any]]) -> [[String:Any]]{
    var arr = array
    for i in 0...arr.count - 1 {
        var dict = arr[i]
        let name_list = dict["name_list"] as! [[String:Any]]
        let lockedItems = name_list.filter { (item) -> Bool in
            let locked = item["locked"] as! Bool
            if locked == false {
                return true
            }
            return false
        }
        print(lockedItems.count)
        dict["lockedItems"] = lockedItems.count
        arr[i] = dict
    }
    arr = arr.sorted(by: { (item1, item2) -> Bool in
        let lockedcount1 = item1["lockedItems"] as! Int
        let lockedcount2 = item2["lockedItems"] as! Int
        return lockedcount1 < lockedcount2
    })
    return arr
}

var array = sortArr(array: arr)
print(array)

答案 4 :(得分:0)

struct Root {
    let nameList: [NameList]
    let title : String
    init(dictionary: [String: Any]) {
        self.title = dictionary["title"] as? String ?? ""
        self.nameList = (dictionary["name_list"] as? [[String:Any]] ?? []).map(NameList.init)
    }
}

struct NameList {
    let locked: Bool
    let title: String
    init(dictionary: [String: Any]) {
        self.locked =  dictionary["locked"] as? Bool == true
        self.title = dictionary["title"] as? String ?? ""
    }
}

let jsonData = Data("""
[
  {
    "title" : "Languages",
    "name_list" : [
      {
        "title" : "Hindi",
        "locked" : true
      },
      {
        "title" : "Hindi1",
        "locked" : true
      },
      {
        "title" : "Hindi2",
        "locked" : false
      },
      {
        "title" : "Hindi3",
        "locked" : true
      },
      {
        "title" : "Hindi4",
        "locked" : false
      }
    ]
  },
  {
    "title" : "Subject",
    "name_list" : [
      {
        "title" : "Hindi4",
        "locked" : false
      },
      {
        "title" : "Hindi4",
        "locked" : true
      },
      {
        "title" : "Hindi4",
        "locked" : true
      }
    ]
  }
]
""".utf8)

let dictionaries = (try? JSONSerialization.jsonObject(with: jsonData)) as? [[String:Any]] ?? []

print("\nAll Models", terminator: "\n============\n")
let models = dictionaries.map(Root.init)
for model in models {
    print(model.title)
    for name in model.nameList {
        print(name.title)
     }
}
print("\nunlockedModels", terminator: "\n============\n")
let unlockedDictionary: [String: [NameList]] = models.reduce(into: [:]) {
    $0[$1.title] = $1.nameList.filter{ $0.locked}
}
for (title, nameList) in unlockedDictionary {
    print(title)
    for name in nameList {
        print(name.title)
    }
}