我有一本字典,里面有一把钥匙我想做多次排序。 但是,一个键不能按字母顺序排序,也没有意义。 这些键只能有一组已定义的值,我尝试使用指定的顺序进行排序。
第二种排序很简单,所以我可以使用排序描述符方式,它可以正常工作:
let costSort = NSSortDescriptor( key: "cmc", ascending: false )
let sortDescriptors = [costSort]
let sortedCards = cards.sortedArrayUsingDescriptors( sortDescriptors )
另一个密钥必须按照数组指定的特定顺序排序:
let rarity = ["Special", "Mythic rare", "Rare", "Uncommon", "Common", "Basic Land"]
所以,根本不是字母顺序,但我需要确保排序遵循这种顺序。 我不确定如何编码。
示例记录:
let cards = [
["name": "card1", "rarity": "Common", "cmc": 2],
["name": "card2", "rarity": "Rare", "cmc": 4],
["name": "card3", "rarity": "Common", "cmc": 1],
["name": "card4", "rarity": "Mythic rare", "cmc": 8]
]
目标是使用[raritySort,costSort]的排序结果为:
card4
card2
card1
card3
答案 0 :(得分:2)
如果您想使用NSArray
排序方法,您可以使用基于自定义NSSortDescriptor
的{{1}}来执行此类操作,查找数组中稀有度的索引,并使用它们来确定相对排名/排序:
NSComparator
最后,let rarities = ["Special", "Mythic rare", "Rare", "Uncommon", "Common", "Basic Land"]
let cards = [
["name": "card1", "rarity": "Common", "cmc": 2],
["name": "card2", "rarity": "Rare", "cmc": 4],
["name": "card3", "rarity": "Common", "cmc": 1],
["name": "card5", "rarity": "Common", "cmc": 7],
["name": "card6", "rarity": "Common", "cmc": 0],
["name": "card4", "rarity": "Mythic rare", "cmc": 8]
]
let nsarrayCards = cards as NSArray
let costSort = NSSortDescriptor( key: "cmc", ascending: false )
let raritySort = NSSortDescriptor(key: "rarity", ascending: false, comparator: { (leftRarity, rightRarity) -> NSComparisonResult in
if let leftRarityIdx = find(rarities, leftRarity as String) {
if let rightRarityIdx = find(rarities, rightRarity as String) {
if rightRarityIdx == leftRarityIdx {
return .OrderedSame
}
return leftRarityIdx > rightRarityIdx ? .OrderedAscending : .OrderedDescending
}
}
return .OrderedSame
})
let sortDescriptors = [raritySort, costSort]
let sortedCards = nsarrayCards.sortedArrayUsingDescriptors( sortDescriptors )
包含:
sortedCards
答案 1 :(得分:2)
这是一个可能的解决方案。使用Swift的排序方法和闭包而不是NSSortDescriptor。
var cards = [
["name": "card1", "rarity": "Common", "cmc": 2],
["name": "card2", "rarity": "Rare", "cmc": 4],
["name": "card3", "rarity": "Common", "cmc": 1],
["name": "card4", "rarity": "Mythic rare", "cmc": 8]
]
let rarity = ["Special", "Mythic rare", "Rare", "Uncommon", "Common", "Basic Land"]
var sortedCards = sorted(cards) {
find(rarity, $0["rarity"] as String) > find(rarity, $1["rarity"] as String) || $0["cmc"] as Int >= $1["cmc"] as Int
}
println(sortedCards)
我在这里使用了更简洁的闭包语法。您也可以像这样展开它:
var sortedCards = sorted(cards, { (d1, d2) -> Bool in
if find(rarity, d1["rarity"] as String) > find(rarity, d2["rarity"] as String){
return true
}
return d1["cmc"] as Int >= d2["cmc"] as Int
})
答案 2 :(得分:0)
这个怎么样?
let sortedCards = cards.sorted { (d1, d2) -> Bool in
d1.valueForKey("cmc") as Int > d2.valueForKey("cmc") as Int
}
好的,这个怎么样?
var cards = [
["name": "card1", "rarity": "Common", "cmc": 2],
["name": "card2", "rarity": "Rare", "cmc": 4],
["name": "card3", "rarity": "Common", "cmc": 1],
["name": "card4", "rarity": "Mythic rare", "cmc": 8]
]
let rarity = ["Special": 1, "Mythic rare": 2, "Rare": 3, "Uncommon": 4, "Common": 5, "Basic Land": 6]
let sortedCards = cards.sorted { (d1, d2) -> Bool in
let d1R: Int = rarity[d1.valueForKey("rarity") as String]!
let d2R: Int = rarity[d2.valueForKey("rarity") as String]!
if d1R == d2R {
return d1.valueForKey("cmc") as Int > d2.valueForKey("cmc") as Int
} else {
return d1R < d2R
}
}