This is related to iOS programing but its mostly swift code so I hope its ok here. The other places to ask these questions get far fewer to none in replies.
Since Swift does not have an Ordered Dictionary and I don't yet want to use an external library im working through variations of manipulating data arrays.
In this example I am presorting an array into multi-dimensional arrays to allow UITableView to read them as multi sections
While I wrote this a few days ago, and I hard tested it and it works, I come back to it today and im like wut!? I know what it needs to do, but I don't like how it reads and know I could do it cleaner, which is why I am here.
It needs to take an array of records, for each record wrap it into a new struct and generate a key using the openingDate for the record, add this new struct to a dictionary for uniqueness and sorting
Then take that dictionary and sort it by those named keys as dates it into an array of tuples.
Then move those tuples into a array as a mock Ordered dictionary for latter use
Thank you for any guidance
struct MockRecordDictionaryRow {
let key : String
let records : [DataRecordWrapped]
}
struct DataRecordWrapped {
var key : String // in the format of Mon 3098
let dateObject : Date
let dateStringOriginal : String
let dataRecord : DataRecord
init(dataRecord: DataRecord, dateStringOriginal : String){
self.key = ""
self.dataRecord = dataRecord
self.dateStringOriginal = dateStringOriginal
//self.dateObject = Date()
let dateFormat = "yyyy-MM-dd" // we atleast know the format from the json!!!
let dateFormatterGet = DateFormatter()
dateFormatterGet.dateFormat = dateFormat
let gettingDate = dateFormatterGet.date(from: dateStringOriginal)
if gettingDate != nil{
self.dateObject = gettingDate!
// auto build in the key
dateFormatterGet.dateFormat = "MMM y"
self.key = dateFormatterGet.string(from: gettingDate!)
}
else {
self.dateObject = Date() // ?!??!?!! like when???
}
}
}
// Main sorting function
func sortAndSplitRecords(_ records : [DataRecord]) -> [MockRecordDictionaryRow] {
// prep a dictionary from the dates
var recordByDateDictionary : [String : [DataRecordWrapped] ] = [:]
// we won't sort the pending, the'll just be attached on later
// these did not have opening dates
var pendingEvents : [DataRecordWrapped] = []
for item in records {
let ww = DataRecordWrapped(dataRecord: item, dateStringOriginal: item.openeningDate?.openingDate ?? "")
if ww.key.isEmpty == false {
let key = ww.key
if recordByDateDictionary.keys.contains(key) == false {
recordByDateDictionary[key] = []
}
recordByDateDictionary[key]?.append(ww)
//else if ww.key.isEmpty == true {}
}
// we dont know how to handle the events that have no opening date yet
else if ww.key.isEmpty == true{
pendingEvents.append(ww)
}
}
// we need to sort the dictioanry
// sort the dictionary into a tuples array
let datefind22 = DateFormatter()
datefind22.dateFormat = "MMM-yy"
// sort records by date into new array, why?
var sorting3_dictionaryToTuples = recordByDateDictionary.sorted {
let first = datefind22.date(from: $0.key)
let second = datefind22.date(from: $1.key)
return first! > second!
}
// at this point we have an array of tuples
// which looks to be (key:String, value:[DataRecordWrapped])
// its not really the struct we were after
// could process it once more but thats changing the same and the type
// but thats better still, so hmmmmm looking for a solution like maybe casting
// look into https://github.com/apple/swift-collections/blob/main/Documentation/OrderedDictionary.md
// for now lets hitch the pendingEvents into the bottom of the stack
if pendingEvents.count > 0 {
let unknowns = (key:"pending", value:pendingEvents)
sorting3_dictionaryToTuples.append(unknowns)
}
// now what??
// can convert to [MockRecordDictionary]
var list : [MockRecordDictionaryRow] = []
for item in sorting3_dictionaryToTuples {
let yy = MockRecordDictionaryRow(key: item.key, records: item.value)
list.append(yy)
}
return list
}