如何使用键值将数组与字典分组。

How can I group an array with dictionaries using a Key value.

我正在与 Json 合作,它有类似这样的响应

{"Type": "ABCDEF", "user_photo": "c16a8ad9bf08f966.jpg", "time": 1540399975658}

所以我使用自定义函数将其转换为以下内容,以便我可以看到 Today, Yesterday, last week, Last month 等的值

{"Type": "ABCDEF", "user_photo": "c16a8ad9bf08f966.jpg", "time": "Today"}

现在我尝试在不同部分使用此结构在表格视图上显示此内容,每个部分显示特定时间的项目。

今天的所有项目都将在一个部分中。昨天的所有项目将在一个部分以此类推。

我有一个包含所有这些响应的数组,我试图将它们分组到一个字典中,每个键值都具有相同的 time 键。如果我能够解决这个问题,我想将它们用于部分会很容易

我被困在这个问题上,不太确定我该如何继续。

1 我尝试但失败的解决方案是拥有一组时间和匹配的响应数组。尝试对 Times 数组进行分组,但没有成功。

创建类型为 [String: [Item]] 的空字典。

var dict = [String: [Item]]()

遍历原始数组中的所有项目并进行下一步。如果没有给定名称的键,则创建空数组并附加一个项目,否则在现有数组中添加项目。

for item in items {
    dict[item.time, default: []].append(item)
}

调用dict["Today"],你会得到一组时间为"Today"的项目。


Swift 4

Dictionary(grouping: items, by: { [=12=].time })

您可以使用原始 JSON 字符串中的数组,然后以您自己的方式解析它。

因此,您将分组问题与解析问题分开了。

如以下代码所示,在 playground 中尝试。

    let array = ["{\"Type\": \"ABCDEF\", \"user_photo\": \"c16a8ad9bf08f966.jpg\", \"time\": \"last week\"}", "{\"Type\": \"ABCDEF\", \"user_photo\": \"c16a8ad9bf08f966.jpg\", \"time\": \"Tomorrow\"}" , "{\"Type\": \"ABCDEF\", \"user_photo\": \"c16a8ad9bf08f966.jpg\", \"time\": \"Today\"}","{\"Type\": \"ABCDEF\", \"user_photo\": \"c16a8ad9bf08f966.jpg\", \"time\": \"Today\"}"]
    let re = try  NSRegularExpression.init(pattern: "(\\"([^\"])*\\")[\s}]+$", options:  [.anchorsMatchLines ,. allowCommentsAndWhitespace])
    let dict =  Dictionary.init(grouping: array) {
            return ([=10=] as NSString).substring(with: re.matches(in: [=10=], options: [], range: NSRange.init(location: 0, length: [=10=].count))[0].range(at: 1))
    }
    print(dict)

结果是:

 ["\"last week \"": ["{\"Type\": \"ABCDEF\", \"user_photo\": \"c16a8ad9bf08f966.jpg\", \"time\": \"last week \"  }"], "\"Tomorrow\"": ["{\"Type\": \"ABCDEF\", \"user_photo\": \"c16a8ad9bf08f966.jpg\", \"time\": \"Tomorrow\"}"], "\"Today\"": ["{\"Type\": \"ABCDEF\", \"user_photo\": \"c16a8ad9bf08f966.jpg\", \"time\": \"Today\"}", "{\"Type\": \"ABCDEF\", \"user_photo\": \"c16a8ad9bf08f966.jpg\", \"time\": \"Today\"}"]]

您可以定义一个包含所有通知的字典:

var notifcationsDict: [String: [Notification]] = ["Today": [],
                                                  "Yesterday": [],
                                                  "Last week": [],
                                                  "Last month": [],]

定义通知结构:

struct Notification: Decodable {
    let type, userPhoto, time: String

    enum CodingKeys: String, CodingKey {
        case type = "Type"
        case userPhoto = "user_photo"
        case time
    }
}

(注意使用编码键以符合Swift命名属性的方式)

然后你可以解码 json 并将通知附加到字典中相应的键:

let json = """
{
    "Type": "ABCDEF",
    "user_photo": "c16a8ad9bf08f966.jpg",
    "time": "Today"
}
"""

guard let jsonData = json.data(using: .utf8) else {
    fatalError("Couldn't get the json to data")
}

do {
    let notification = try JSONDecoder().decode(Notification.self, from: jsonData)
    notifcationsDict[notification.time]?.append(notification)
    print(notifcationsDict)
} catch {
    print(error)
}