【问题标题】:Iterate array of dictionary and sort based on key迭代字典数组并根据键排序
【发布时间】:2021-07-07 05:17:35
【问题描述】:

我有字典数组,值如下:

    [["-MXpvzmZdbqzrjND8w9F": {
    lid = "-MW6eEidZFCLeeZ0uBk1";
    message = hi;
    timeStamp = 1617960107264;
    title = "Sambhar Dosa";
    user = 1QSU0c1q8QNrZzmICXGClC0o86E3;
}, "-MXq5NAyrkk4ZcvRFM7T": {
    lid = "-MW6eEidZFCLeeZ0uBk1";
    message = "how ru?";
    timeStamp = 1617962828647;
    title = "Sambhar Dosa";
    user = 1QSU0c1q8QNrZzmICXGClC0o86E3;
}], ["-MXqa5-pkC28lY_Q_hpZ": {
    lid = "-MWwEpHAhIdhN0i5sltB";
    message = "hi nice cycle";
    timeStamp = 1617971142820;
    title = "Cycle for kids";
    user = 1QSU0c1q8QNrZzmICXGClC0o86E3;
}]]

这里数组中有 2 个元素。我想取两个数组中的最后一个元素并根据时间戳值对其进行排序。 怎么做?请帮帮我。

【问题讨论】:

  • 请提供您如何在 Swift 中表示您的示例数据。
  • 这不是javascript。这个数据来自firebase数据库。如果你观察,数组中有2个元素。
  • var testArray = [[String : Any]]()。这是存储上述值的字典数组。
  • 啊...好吧,但是您肯定有一些 Swift 类型来表示存储在字典中的值吗?或者你真的写过(testArray[I][key] as? [String:Any])?["timeStamp"] as? Int这样的代码吗?
  • 我还没有获取时间戳。就像我说的,字典数组的值高于数组中的 2 个元素。数组的第一个元素有 2 个字典,第二个元素有 1 个字典。现在必须根据它们的时间戳键对这些元素进行排序。

标签: arrays swift sorting dictionary timestamp


【解决方案1】:

从cmets看来,数组的类型是:

typealias SomeDataArray = [[String: [String: Any]]]

所以我们从一开始就缺少类型安全。我要做的第一件事是在该定义中定义一个struct 来代表Any。现在,我将使用 struct 作为内部字典的包装器,对所有字段使用计算属性:

struct SomeData
{
    let dict: [String: Any]

    var lid: String? { dict["lid"] as? String }
    var message: String? { dict["message"] as? String }
    var timeStamp: Int { dict["timeStamp"] as? Int ?? 0 }
    var title: String? { dict["title"] as? String }
    // Skipping user, because I have no idea what to make of its type.
}

确实应该将其解码为某种真正的 Swift 类型,但这是另一天的话题。

所以现在我们重做typealias

typealias SomeDataArray = [[String: SomeData]]

在聊天中解释了这些字典中的每一个的“最后一个”元素中的哪些内容可以定义为具有最大 timeStamp 值的那个。鉴于这将提供此解决方案(保留密钥)

let results = testData.map {
    dict in dict.map {
        ($0.key, SomeData(dict: $0.value))
    }.sorted { $0.1.timeStamp < $1.1.timeStamp }.last
}.filter { $0 != nil }.map { $0! }.sorted { $0.1.timeStamp < $1.1.timeStamp }

如果您想将它转换回您从 Firebase 获得的 [[String;Any]],那么应该是这样的:

let results = testData.map {
    dict in dict.map {
        ($0.key, SomeData(dict: $0.value))
    }.sorted { $0.1.timeStamp < $1.1.timeStamp }.last
}.filter { $0 != nil }.map { $0! }.sorted { $0.1.timeStamp < $1.1.timeStamp }
.map { [$0.0: $0.1.dict as Any] }

【讨论】:

    猜你喜欢
    • 2015-01-04
    • 2012-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-11
    • 2014-10-23
    • 1970-01-01
    相关资源
    最近更新 更多