将3个单独的字典数组转换为1个结构数组?

时间:2017-03-31 16:30:06

标签: ios swift3

我目前正在使用3个独立的数组来填充分段的UITableView,我只想使用单个数组进行过滤,但仍然维护我的表中的部分。

数据由单个JSON字符串提供,然后我会迭代以创建单个“事件”的字典。然后根据'事件状态'的值,将其添加到三个数组之一(打开,关闭和延迟)。然后使用这些数组填充UITableView的每个部分。

let myDictionary: [String: String] = [
      "EventID" : item["EventID"] as! String,
      "EventTitle" : item["EventTitle"] as! String,
      "EventSummary" : item["EventSummary"] as! String,
      "EventStatus" : item["Status"] as! String
      ]

 if (item["Status"] as! String == "Open") {
     self.openEvents.append(myDictionary as AnyObject)
 }
 if (item["Status"] as! String == "Closed") {
     self.closedEvents.append(myDictionary as AnyObject)
 }
 if (item["Status"] as! String == "") {
     self.deferredEvents.append(myDictionary as AnyObject)
 }

然后在cellForRowAt:

var tmpDict: [String: String] = ["":""]

if sectionHeaders[indexPath.section] == "Open" {
    tmpDict = openEvents[indexPath.row] as! [String : String]
}

if sectionHeaders[indexPath.section] == "Closed" {
    tmpDict = closedEvents[indexPath.row] as! [String : String]
}

if sectionHeaders[indexPath.section] == "Deferred" {
    tmpDict = deferredEvents[indexPath.row] as! [String : String]
}

问题是,为了允许过滤这些数据,我必须针对三个不同的阵列运行过滤器,这意味着三个不同的过滤数据'阵列。这远非理想。

我想要实现的是拥有一个结构化数据阵列(与字典相对),用户可以过滤这些数据并将结果返回到单个过滤后的数据中。阵列。我在其他地方这样做效果很好,但是,这是一个单独的列表,而不是分段。

我有一个结构设置并按如下方式添加项目:

let data = EventItem(EventID: item["EventID"] as! String, EventTitle: item["EventTitle"] as! String, EventSummary: item["EventSummary"] as! String, EventStatus: item["Status"] as! String)

self.eventList.append(data)

并使用以下过滤:

filteredData = eventList.filter() {
   ($0.EventTitle.lowercased() as NSString).contains(searchText.lowercased()) || ($0.EventSummary.lowercased() as NSString).contains(searchText.lowercased())
}

eventsTable.reloadData()

是否可以将此单个数组拆分为TableView中的不同部分?如果是这样,怎么样?

2 个答案:

答案 0 :(得分:0)

您可以使用filteredData

已有方法的扩展名
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
    switch section {
    case 0:
        let sortedList = newItems.sorted { $0.eventStatus == "Open"}
        return sortedList.count
    case 1:
        let sortedList = newItems.sorted { $0.eventStatus == "Closed"}
        return sortedList.count
    case 2:
        let sortedList = newItems.sorted { $0.eventStatus == ""}
        return sortedList.count
    default:
        return 0 // shouldn't happen
    }
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
    var tmpDict: [String: String] = ["":""]

    switch section {
    case 0:
        tmpDict = newItems.sorted { $0.eventStatus == "Open"}
    case 1:
        tmpDict = newItems.sorted { $0.eventStatus == "Closed"}
    case 2:
        tmpDict = newItems.sorted { $0.eventStatus == ""}
    default:
        return 0 // shouldn't happen

    // setup cell
}

答案 1 :(得分:0)

我建议您对EventItem结构承担更多责任,以帮助处理数据源响应。然后,您可以使用二维数组来管理节和行内容。

例如:

struct EventItem
{
      var EventID        = ""
      var EventTitle     = ""
      var EventSummary   = ""
      var EventStatus    = ""

      func matches(_ searchText:String) -> Bool
      {
         return EventTitle.lowercased().contains(searchText.lowercased())
             || EventSummary.lowercased().contains(searchText.lowercased())
      }

      var section:Int
      {
         return EventStatus == "Opened"  ?  0
              : EventStatus == "Closed"  ?  1
              :                             2
      }
}

// you can maintain an "master" array of events (or build them from the dictionary as needed)
// I' using an array to keep the example simple

var eventList:[EventItem] = []

// This 2D array in your controller will serve as the store for your table view data source
var sectionData:[[EventItem]] = []

// applying filter is one line once you've added utility functions to your struct
sectionData = Array(0..<3).map{ section in return eventList.filter{$0.section == section && $0.matches(searchText)} }

// responding to tableview data source protocol only requires one line
// (which will not change even if you break down your data into more sections)
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{ return sectionData[section].count }

// getting to the data to populate the table view cell will be quite straightforward
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
    let rowData = sectionData[indexPath.section][indexPath.row]
    // setup cell ...
}