Reputation: 69
I have array of dictionary and the values are as follows:
[["-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;
}]]
Here there are 2 elements in the array. I want to take the last element in both of the array and sort it based on the timestamp value. How to do it? Please help me.
Upvotes: 1
Views: 134
Reputation: 2805
From comments, it seems that that the type of the array is:
typealias SomeDataArray = [[String: [String: Any]]]
So we're missing type safety from the beginning. The first thing I'd do is define a struct
to represent Any
in that definition. For now I'll just use a struct
as a wrapper for the inner dictionary, using computed properties for all the fields:
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.
}
Really this should be decoded into some real Swift type, but that's a topic for another day.
So now we redo the typealias
typealias SomeDataArray = [[String: SomeData]]
In chat it was explained what within the "last" element for each of these dictionaries can be defined as the one with the largest timeStamp value. Given that this will give this solution (retaining the keys)
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 }
If you want to transform it back the [[String;Any]]
you get from Firebase, then it would be this:
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] }
Upvotes: 1