我有一個名為DataModel2 個帶有字串值的屬性的模型。該模型的串列如下所示。
struct DataModel: Hashable, Codable {
var value: String
var optionalKey: String?
}
[
{
value: "100",
optionalKey: "value"
},
{
value: "200"
},
{
value: "300",
optionalKey: ""
},
{
value: "400",
optionalKey: "value"
}
]
如何安全地對串列進行排序,以便存在“可選鍵”的任何物件都位于串列的開頭。期望的結果如下:
[
{
value: "100",
optionalKey: "value"
},
{
value: "400",
optionalKey: "value"
}
{
value: "200"
},
{
value: "300",
optionalKey: "" // <- empty string to be treated as if key does not exist
}
]
uj5u.com熱心網友回復:
如果您要反序列化 JSON 并希望空字串為零,則可以實作自定義init函式:
extension DataModel {
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
value = try values.decode(String.self, forKey: .value)
let optionalKey = try? values.decode(String.self, forKey: .optionalKey)
// If `optionalKey` string has no characters assign nil
self.optionalKey = optionalKey?.count == 0 ? nil : optionalKey
}
}
然后根據optionalKey值的存在對串列進行排序:
let list: [DataModel] = decodedData.sorted(by: { lhs, rhs in
// `true` if left side is not `nil` and right side is `nil`
// in other words, non-nil gets priority in the list
return lhs.optionalKey != nil && rhs.optionalKey == nil
})
uj5u.com熱心網友回復:
要始終獲取optionalKey最后排序為 nil 或空的物件,您可以這樣做
let sorted = values.sorted(by: {
let first = ($0.optionalKey ?? "").isEmpty ? 0 : 1
let second = ($1.optionalKey ?? "").isEmpty ? 0 : 1
return first > second
})
替代解決方案
return !($0.optionalKey?.isEmpty ?? true) && ($1.optionalKey?.isEmpty ?? true)
uj5u.com熱心網友回復:
排序閉包非常簡單。
您比較兩個物件:object1& object2,object1第一個引數閉包在哪里object2,第二個是閉包。在這里他們是DataModel實體。您可以通過回傳或比較它們
來決定這兩個可以是陣列中的任何物件。
在引擎蓋下,它可以是任何排序方法(氣泡等),沒關系。你只需要比較兩個元素,然后決定哪一個應該在另一個之前。truefalse
這就是您應該能夠撰寫的代碼:
let explicit = models.sorted { object1, object2 in
// They both have optionalKey value
if let optional1 = object1.optionalKey, let optional2 = object2.optionalKey {
if optional1.isEmpty && !optional2.isEmpty { //One if empty -> The other one should go first
return false
} else if !optional1.isEmpty && optional2.isEmpty { //One if empty -> The other one should go first (the other version)
return true
} else { //They are both empties OR both non-empty, we compare then just with value
return object1.value < object2.value
}
} else if let optional1 = object1.optionalKey { //Here, only object2 had nil optionalKey value
if optional1.isEmpty { //optionKey of object1 exists, but is empty
return false
} else { //optionKey of object1 exists, and is not empty
return true
}
} else if let optional2 = object2.optionalKey { //Here, only object2 had nil optionalKey value
if optional2.isEmpty { //optionKey of object1 exists, but is empty
return true
} else { //optionKey of object2 exists, and is not empty
return false
}
} else { //Both are nil
return object1.value < object2.value
}
}
print(explicit)
它很冗長,但要逐案處理,現在我們可以簡化它:
let sorted = models.sorted { object1, object2 in
//Since in your case being nil or empty is the same, let's simplify with giving empty value directly
let optionalValue1 = object1.optionalKey ?? ""
let optionalValue2 = object2.optionalKey ?? ""
if optionalValue1.isEmpty && !optionalValue2.isEmpty {
return false
} else if !optionalValue1.isEmpty && optionalValue2.isEmpty {
return true
} else {
return object1.value < object2.value
}
}
print(sorted)
可能會有更多不那么冗長的代碼,但是由于您甚至無法對其進行詳細排序,所以我會盡可能地“簡化”它。您仍然需要了解它以在將來對其進行除錯/更改。
現在,我稍后再說,但是您可能不會像那樣比較字串值,因為它們是“數字”。例如,如果你有"2"and "10",在字串比較中,"10"低于"2",所以你需要替換object1.value < object2.value為object1.value.compare(object2.value, options: .numeric) != .orderedDescending
uj5u.com熱心網友回復:
如果您想根據optionalKey status 和value對 DataModel 物件陣列進行排序,您應該在下面查看我的代碼。
陣列元素有 optionalKey,先按值排序,再將其他陣列元素排序。
private func sortDataObjectByValue() -> [DataModel]{
let models = [
DataModel(value: "100", optionalKey: "value"),
DataModel(value: "800", optionalKey: ""),
DataModel(value: "1800", optionalKey: "value"),
DataModel(value: "1200"),
DataModel(value: "900", optionalKey: ""),
DataModel(value: "500", optionalKey: "value")
]
var sortedModels:[DataModel] = []
var modelsWithKey:[DataModel] = []
var modelsWithoutKey:[DataModel] = []
for model in models {
if let key = model.optionalKey, key != "" {
modelsWithKey.append(model)
}
else {
modelsWithoutKey.append(model)
}
}
modelsWithKey = modelsWithKey.sorted(by: { (Int($0.value) ?? 0) < (Int($1.value) ?? 0) } )
sortedModels = modelsWithKey
modelsWithoutKey = modelsWithoutKey.sorted(by: { (Int($0.value) ?? 0) < (Int($1.value) ?? 0) } )
sortedModels = modelsWithoutKey
debugPrint(sortedModels)
return sortedModels
}
0:DataModel - value:“100” optionalKey:可選 - some:“value”
1:DataModel - value:“500” optionalKey:可選 - some:“value”
2:DataModel - value:“1800” optionalKey:可選 - some:“value”
3:資料模型 - 值:“800” 可選鍵:可選 - 一些:“”
4:資料模型 - 值:“900” 可選鍵:可選 - 一些:“”
5:資料模型-值:“1200”-可選鍵:無
現在您已經根據 optionalKey 狀態和值對 DataModel 陣列進行了排序。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/476592.html
標籤:迅速
