【问题标题】:Merging synched data from arrays and sorting swift合并来自数组的同步数据并快速排序
【发布时间】:2021-11-13 16:48:13
【问题描述】:

我从 Firebase 中提取了三个数据数组,这些数据通过它们的索引同步。我在表格中显示这些数据。数据被拉入并使用结构存储。

我想提供选项以两种不同的方式对数据进行排序,然后在表格中显示 a。我计划使用分段控件在两种不同类型之间切换。

由于数据位于 3 个单独的数组中,通过索引排序同步一个数组不会对其他数组中的相应数据进行排序并中断同步。所以假设解决方案是将这些数据放在一个数组中,然后可以对其进行排序并填充表格。

我已经尝试了各种方法,最好的进展是使用稍微修改过的 zip 序列来填充新的二维数组。但我未能填充新数组。

    struct RTrackedSports {
        var documentId: String?
        var rPostedBy: String?
        var rSyncTimeStringArray: [String]?
        var rSyncDateArray: [Timestamp]?
        var rSyncEventNameArray: [String]?
        var rUID: String?
    }

    var rSelectedRecord: [RTrackedSports] = []

    override func viewDidLoad() {
        super.viewDidLoad()
        
        resultsTable.dataSource = self
        resultsTable.delegate = self
        
        arrayMasher()
    }

    func arrayMasher() {

        //CODE TO BRING ARRAY DATA TOGETHER HERE
        
        }

//how my table is currently populated
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return rSelectedRecord[0].rSyncTimeStringArray!.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "rCell", for: indexPath) as! ResultTableViewCell
    cell.rEvent.text = rSelectedRecord[0].rSyncEventNameArray![indexPath.row]
    cell.rEventTime.text = rSelectedRecord[0].rSyncTimeStringArray![indexPath.row]

    return cell
}

如果这也有帮助的话,这是我在 IB 中的原型单元配置...

我对 swift 还是很陌生,所以任何帮助表示赞赏。抱歉,如果这是一个愚蠢的问题,感觉它应该有一个简单的解决方案,但我无法将它拼凑起来。

如果有帮助的话,很高兴分享我在 arrayMasher 上失败的尝试,但我不确定它会不会。以下是我正在使用的数据示例...

[appName.RTrackedSports(documentId: Optional("uVIJJIzs3ux3yZBkRwaB"), rPostedBy: Optional("Dvufj9y2W3ZYB4WWYWcKEuaDOdA2"), rSyncTimeStringArray: Optional(["00:00:20:00", "00:00:30:00", "00:00:10:00", "00:00:00:05"]), rSyncDateArray: Optional([<FIRTimestamp: seconds=1631401200 nanoseconds=0>, <FIRTimestamp: seconds=1631487600 nanoseconds=0>, <FIRTimestamp: seconds=1631574000 nanoseconds=0>, <FIRTimestamp: seconds=1631660400 nanoseconds=0>]), rSyncEventNameArray: Optional(["Tickton", "Beverley", "Hornsea", "Bridlington"]))]

【问题讨论】:

  • 阅读您的问题,我了解了事情的一般要点,但是您包含的代码非常模糊。您说要组合三个数组,但您的示例代码只有两个 RTrackedSports 数组。示例数据不可复制粘贴,因为您刚刚包含了 Xcode 控制台输出。你能包括一些人们可以实际使用的东西吗?我也不清楚关于如何组合数组的准则是什么。另外,为什么要按索引同步?为什么不使用唯一 ID? rUID 不是这样吗?
  • 抱歉不清楚,这三个数组是 rSyncTimeStringArray、rSyncDateArray、rSyncEventNameArray,当我从 firebase 中提取数据时,这三个数组就存放在这里。 rTimeString、rEventDate 和 rEventName 是我正在玩的一些空数组,抱歉造成混淆,删除了这些。 UID 是我应用于整个记录/文档的唯一 ID,而不是文档内的三个数组。我只是假设它们必须通过索引同步,因为表格循环遍历数据并显示它的方式。如果有帮助,我已在表格代码和 IB 屏幕截图中添加
  • 我会说您应该使用可以将元素联系在一起的通用 ID 来存储数据。从帖子中现在还不清楚数据结构是如何工作的,但目前似乎不是这种情况,但它会解决问题
  • 我刚刚在下面发布了一个可行的解决方案,这可能是实现预期目标的更简单方法,但它确实有效!

标签: arrays swift sorting struct zip


【解决方案1】:

好的,所以最终提出了这个解决方案,它使用 zip 将三个数组混合成一个使用新结构的新数组:

    //NEW STRUCT FOR THE BLENDED TABLE DATA
    struct RTableData {
        var recordId: Int
        var rSyncTimeString: String
        var rSyncDate: Timestamp
        var rSyncEventName: String
    }

    var rResultsmash: [RTableData] = []

    func arrayMasher() {
        //CUSTOMISED ZIP/FOR LOOP
        var i = 0
        for (Names, (Times, Dates)) in zip(rSelectedRecord[0].rSyncEventNameArray!, zip(rSelectedRecord[0].rSyncTimeStringArray!, rSelectedRecord[0].rSyncDateArray!)) {
            
            rResultsmash.append(RTableData(recordId:i, rSyncTimeString:Times, rSyncDate:Dates, rSyncEventName:Names ));
            i += 1
        }
        //SORT THE DATA BY TIME
        rResultsmash.sort {
            $0.rSyncTimeString < $1.rSyncTimeString
        }
    }
    //LOAD THE DATA INTO THE TABLE
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return rResultsmash.count 
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "rCell", for: indexPath) as! ResultTableViewCell
        cell.rEvent.text = rResultsmash[indexPath.row].rSyncEventName
        cell.rEventTime.text = rResultsmash[indexPath.row].rSyncTimeString
        cell.rEventPos.text = "\(indexPath.row + 1)"

        return cell
    }
    //SWITCH TO CHANGE FILTER AND RELOAD TABLE DATA
    @IBAction func segmentedControlClicked(_ sender: UISegmentedControl) {
            switch segmentedControl.selectedSegmentIndex {
            case 0:
                rResultsmash.sort {
                    $0.rSyncTimeString < $1.rSyncTimeString
                }
                resultsTable.reloadData()
            case 1:
                rResultsmash.sort {

                    $0.rSyncDate < $1.rSyncDate
                }
                resultsTable.reloadData()
            default:
                print("THIS IS DEFAULT")
            }
    }

我想有一种更简单的方法可以做到这一点,但它确实有效!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-06
    • 2010-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多