[英]Sort/Filter dictionary by property of object in Key
我有一個字典,例如:
let dict = Dictionary<Month, Array<Int32>>()
Obj1.price = "10"
Obj1.value = "abc"
Obj1.title = "January"
Obj2.price = "10"
Obj2.value = "def"
Obj2.title = "April"
Obj3.price = "10"
Obj3.value = "pqr"
Obj3.title = "February"
Obj4.price = "4"
Obj4.value = "mnq"
Obj4.title = "April"
dict = [ Obj1: [3,4], Obj2 : [1,2], Obj3: [8,9], Obj4: [3,3] ]
我有一個自定義的月份數組
let sortTemplate = ["April", "May", "June", "July", "August", "September", "October", "November", "December", "January", "February", "March"]
我想將字典排序為[Obj2:[1,2],Obj4:[3,3],Obj1:[3,4],Obj3:[8,9]]
簡而言之,我期望根據key屬性的自定義引用數組對字典進行排序。 我知道我們無法對字典進行排序,但希望根據自定義sortTemplate進行排序並插入字典數組中
在這方面的任何提示都是有用的。 我知道我們可以用值和鍵排序
這是使用Dictionary
的內置排序功能的一種可能的解決方案,但是在示例中將title
屬性顯示為自定義enum
而不是String
。 然后,按enum
月份的順序隱式給出“排序模板”。
即, enum MonthSortTemplate
和您的類MyClass
(后者沒有為我們洗澡,所以我自己做了一個MWE):
enum MonthSortTemplate: Int {
case April = 1
case January
case February
// ... rest of months follows, in the order you prefer
}
class MyClass {
var price = ""
var value = ""
var title: MonthSortTemplate = .April
}
// Hashable (just some dummy, don't know how you've set this up)
extension MyClass: Hashable {
var hashValue: Int {
return price.hashValue ^ value.hashValue
}
}
// Equatable (just some dummy, don't know how you've set this up)
func ==(lhs: MyClass, rhs: MyClass) -> Bool {
return lhs.price == rhs.price && lhs.value == rhs.value
}
創建您的MyClass
實例,添加到您的字典中,並使用后者的.sort(...)
函數進行自定義閉包,該閉包為此特定類型的比較指定。
var Obj1 = MyClass()
var Obj2 = MyClass()
var Obj3 = MyClass()
Obj1.price = "10"
Obj1.value = "abc"
Obj1.title = .January
Obj2.price = "10"
Obj2.value = "def"
Obj2.title = .April
Obj3.price = "10"
Obj3.value = "pqr"
Obj3.title = .February
var dict = Dictionary<MyClass, Array<Int32>>()
dict = [ Obj1: [3,4], Obj2 : [1,2], Obj3: [8,9]]
// your custom sort closure, for Dictionary.sort(...) method
let byMonthTemplate = {
(elem1:(key: MyClass, val: [Int32]), elem2:(key: MyClass, val: [Int32]))->Bool in
if elem1.key.title.rawValue < elem2.key.title.rawValue {
return true
} else {
return false
}
}
let sortedDict = dict.sort(byMonthTemplate)
print("\(dict)")
如果您真的很喜歡您的類屬性title
為String
類型,則可以選擇-為MyClass
對象定義<
運算符:
func <(lhs: MyClass, rhs: MyClass) -> Bool {
// do comparison stuff with strings lhs.title and rhs.title
// with regard to your ordering of choice (array sortTemplate)
return ...
}
在這種情況下,“亂七八糟”的東西最終會出現在此功能中,而實際的排序可以如下
let sortedDict = dict.sort { $0.0 < $1.0 }
就個人而言,我更喜歡enum
解決方案(但是,這不在主題之列)。
編輯:
根據您的要求,我將為您的類MyClass
包含<
運算符的一個示例。 這絕不是最佳選擇,但也許您可以從我的示例中對其進行優化。
// add sortTemplate as a static property of MyClass
class MyClass {
var price = ""
var value = ""
var title = ""
static let sortTemplate = ["April", "May", "June", "July", "August", "September", "October", "November", "December", "January", "February", "March"]
}
// define < operator for MyClass objects
func <(lhs: MyClass, rhs: MyClass) -> Bool {
let indexOfLhs = MyClass.sortTemplate.indexOf({$0 == lhs.title})
let indexOfRhs = MyClass.sortTemplate.indexOf({$0 == rhs.title})
return indexOfLhs < indexOfRhs
}
// you can now sort your dictionary according to
let sortedDict = dict.sort { $0.0 < $1.0 }
希望有幫助,快速又骯臟
let dict = ["Obj1":[3,4],"Obj2":[1,2],"Obj3":[8,9],"Obj4":[3,3]]
let dict1 = dict.sort { $0.1[0] < $1.1[0]} //Sort by first object in array
let dict2 = dict1.sort { $0.1[1] < $1.1[1]} //Sort by second object in array
print(dict2)
輸出: [("Obj2", [1, 2]), ("Obj4", [3, 3]), ("Obj1", [3, 4]), ("Obj3", [8, 9])]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.