У меня есть два ответа, но сначала нужно обратиться к нескольким вещам.
Для обоих ваших классов, если вы хотите, чтобы ими управлял Realm, вам нужно включать @objc перед каждой переменной, которую вы хотитеУправляемый
public class Customer :Object {
@objc dynamic var Id : String = ""
или при желании добавить @objcMembers к имени класса
@objcMembers class Customer :Object {
dynamic var Id : String = ""
Другое дело, что свойства класса (переменные) всегда должны быть в нижнем регистре, имена классов должны начинаться с верхнегокейс.Ничто не должно быть все CAPS.
public class Customer :Object {
@objc dynamic var customer_id : String = ""
@objc dynamic var name : String = ""
Первое решение использует вашу текущую структуру:
var topCustomers = [(String, Int)]() //stores the customer id and count in an array of tuples
let results = realm.objects(Bills.self) //get all the bills
let allCustomerIds = results.map{ $0.CustomerId } //get a list of all of the customer id's
let uniqueIds = Set(allCustomerIds) //create a set of unique customer ids
for custId in uniqueIds { //iterate over the array of unique customer id's
let count = results.filter("CustomerId == %@", custId).count // get a count of each customer id from results
topCustomers.append( (custId, count) ) //add the customer id and it's count to the array
}
topCustomers.sort { $0.1 > $1.1 } //sort the array by count
for x in topCustomers { //print out the array - the customer with the most bills will be at the top
print(x.0, x.1)
}
второй, более элегантный подход использует отношения между клиентами и их счетами.Это обеспечит НАМНОГО больше гибкости для генерации отчетов, запросов и общей организации.
Вот обновленные классы:
class CustomerClass: Object {
@objc dynamic var customer_id = UUID().uuidString
@objc dynamic var name = ""
@objc dynamic var address = ""
let billList = List<BillClass>()
override public class func primaryKey() -> String? {
return "customer_id"
}
}
class BillClass: Object {
@objc dynamic var bill_id = UUID().uuidString
@objc dynamic var amount = ""
override public class func primaryKey() -> String? {
return "bill_id"
}
}
, а затем несколько очень коротких кодов для выполнения того же действия, что и впервый пример
let customers = realm.objects(CustomerClass.self) //get all customers
let results = customers.map { ($0.name, $0.billList.count) } //iterate over all, creating tuple with customer name & bill count
let sortedResults = results.sorted(by: { $0.1 > $1.1} ) //sort by bill count, descending
sortedResults.forEach { print($0) } //print the results, customer will most bills at top
Отмечает использование UUID (). uuidString
@objc dynamic var bill_id = UUID().uuidString
создает уникальные первичные ключи для ваших объектов.Устраняет необходимость в индексировании, уникальности, увеличении и т. Д.