使用有序数组对字典排序

时间:2014-09-18 01:01:21

标签: sorting dictionary swift

我有一本字典,里面有一把钥匙我想做多次排序。 但是,一个键不能按字母顺序排序,也没有意义。 这些键只能有一组已定义的值,我尝试使用指定的顺序进行排序。

第二种排序很简单,所以我可以使用排序描述符方式,它可以正常工作:

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

3 个答案:

答案 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
    }

}