Reputation: 2703
I am working with Json which has response something like this
{"Type": "ABCDEF", "user_photo": "c16a8ad9bf08f966.jpg", "time": 1540399975658}
So I converted this to below by using a custom function so that I can see the value for Today, Yesterday, last week, Last month
etc.
{"Type": "ABCDEF", "user_photo": "c16a8ad9bf08f966.jpg", "time": "Today"}
Now I am trying to display this on a tableview using this structure in different section with each section showing up items of particular time.
All items in today will be in one section. All items in yesterday will be in one section so on.
I have an array of all these responses and I am trying to group them into a dictionary with each key value having the same time
key. If I am able to solve this I guess using them for sections would be pretty easy
I am stuck in this and not quite sure how I could continue on this.
1 solution I tried but failed was to have an array of Times and matching array of responses. Tried grouping Times array but it did not work.
Upvotes: 0
Views: 2625
Reputation: 18591
You could define a dictionary with all the notifications:
var notifcationsDict: [String: [Notification]] = ["Today": [],
"Yesterday": [],
"Last week": [],
"Last month": [],]
Define a struct for notifications:
struct Notification: Decodable {
let type, userPhoto, time: String
enum CodingKeys: String, CodingKey {
case type = "Type"
case userPhoto = "user_photo"
case time
}
}
(Notice the use of coding keys to conform to the Swift way of naming properties)
Then you could decode the json and append the notification to the corresponding key in the dictionary:
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)
}
Upvotes: 1
Reputation: 11539
You may use array from the original JSON string and then parse it in your own way.
Thus you have separate a grouping question apart from parsing questions.
As shown in the following code and try it in 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 ($0 as NSString).substring(with: re.matches(in: $0, options: [], range: NSRange.init(location: 0, length: $0.count))[0].range(at: 1))
}
print(dict)
The result is :
["\"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\"}"]]
Upvotes: 1
Reputation: 6718
Create an empty dictionary of type [String: [Item]].
var dict = [String: [Item]]()
Loop through all the items in the original array and make next thing. If there is not a key with the given name, create empty array and append an item, else add item in the existing array.
for item in items {
dict[item.time, default: []].append(item)
}
Call dict["Today"]
and you will get an array of items with the time = "Today".
Swift 4
Dictionary(grouping: items, by: { $0.time })
Upvotes: 2