My Model looks like this-
class Model: Object {
dynamic var id: String?
dynamic var sessionId: String?
static var all: [Model] {
get {
// Get all and return them
}
}
static func getAllModelsGroupedBySessionId() -> [[Model]] {
let all = Model.all
var set = Set<String>()
for element in all {
if let sessionId = element.sessionId {
set.insert(sessionId)
}
}
let uniqueSessionIds = set.map { $0 }
var array: [[Model]] = []
for sessionId in uniqueSessionIds {
var arr:[Model] = []
for element in all {
if element.sessionId == sessionId {
arr.append(element)
}
}
array.append(arr)
}
return array
}
}
My po Model.all
is:
▿ 3 elements
▿ 0 : Model {
id = one;
sessionId = A;
}
▿ 1 : Model {
id = two;
sessionId = B;
}
▿ 2 : Model {
id = three;
sessionId = B;
}
And po Model. getAllModelsGroupedBySessionId()
▿ 2 element
▿ 0 : 1 elements
▿ 0 : Model {
id = one;
sessionId = A;
}
▿ 1 : 2 elements
▿ 0 : Model {
id = two;
sessionId = B;
}
▿ 1 : Model {
id = three;
sessionId = B;
}
So my getAllModelsGroupedBySessionId
works great but I want to if Realm
or Array
provides some api for the same work.
arrayOfArrays = Model. getAllModelsGroupedBySessionId()
An example is-
[[allmodelsWithSessionIdAsOne], [allmodelsWithSessionIdAsTwo]]
I don't want to sort them, I want an "array of arrays", where there is an array of, array of elements of with same session id.
I want to later populate that array in UICollectionView
, where arrayOfarrays.count
is number of section and arrayOfArray[section].count
is number of item in that section.
Realm makes it easy to use relations for grouping. Because Realm is very cheap to fetch relations unlike SQL. In other words, instead of grouping when fetching, save it in a grouped state in advance.
When saving the Model object, You can add code to do grouping at the same time like the following.
let model = Model()
model.sessionId = "..."
...
Group
and addModel()
implemetation is here:
Group.addModel(model)
class Model: Object {
dynamic var id: String?
dynamic var sessionId: String?
}
class Group: Object {
dynamic var sessionId: String?
let models = List<Model>()
static override func primaryKey() -> String? {
return "sessionId"
}
static func addModel(_ model: Model) {
let realm = try! Realm()
if let sessionId = model.sessionId {
if let group = realm.object(ofType: Group.self, forPrimaryKey: sessionId) {
try! realm.write {
group.models.append(model)
}
} else {
let group = Group()
group.sessionId = sessionId
group.models.append(model)
try! realm.write {
realm.add(group)
}
}
}
}
}
You can get same grouped data structure you mentioned, just fetch Group
objects.
realm.objects(Group.self)