как отфильтровать и отобразить значения табличного представления и представления коллекции на основе значения bool в моем json - PullRequest
0 голосов
/ 13 февраля 2019

У меня есть список 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 = subject имеет только один заблокированный = false, но title = language имеет 2 locked = false.Таким образом, в моем табличном представлении должен отображаться первый предмет и язык.

То же самое в каждом представлении коллекции, какой объект locked = 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 голосов
/ 13 февраля 2019
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)
    }
}
0 голосов
/ 13 февраля 2019

Просто используйте эту функцию, и она будет работать для вас, не создавая никаких моделей.

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
}

EDITED

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)
0 голосов
/ 13 февраля 2019

Мое решение здесь состоит в том, чтобы создать функцию в ячейке табличного представления и вызвать ее в 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()
}
0 голосов
/ 13 февраля 2019

В этом случае, если вы хотите отобразить locked == false в качестве первого, вам нужно изменить порядок словаря массива (сортировка по блокировке).а затем загрузить данные в UItableview и UIcollectionview

0 голосов
/ 13 февраля 2019

Я использовал это ниже 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 to

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)
    }
}

Функция для привязки json к структуре модели

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
}

И, наконец, функция, которая сортирует ваш список по количеству заблокированных счетчиков (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.


Если что-то изменится в вашем требовании, дайте мне знать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...