在Swift中对字典进行排序

时间:2015-05-05 13:48:56

标签: swift sorting dictionary

我知道这个话题已经讨论过了,但我无法解决其他答案,所以提前抱歉我的成熟!

我需要按键对此词典进行排序

codeValueDict = ["us": "$", "it": "€", "fr": "€"]

所以我需要一本像这样的字典

sortedDict = ["fr": "€", "it": "€", "us": "$"]

但我无法做到。

我试过这个

let sortedKeysAndValues = sorted(dictionary) { $0.0 < $1.0 }

但是在我需要从这个字典(键和值)创建两个数组之后,使用该解决方案

codesArray = sortedKeysAndValues.keys.array

给我错误&#39; [(String,String)]&#39;没有名为&#39; keys&#39; 的成员,因为该解决方案并未完全返回字典。

所以我尝试了另一种解决方案:

    let prova = codiceNomeDict as NSDictionary
    for (k,v) in (Array(codiceNomeDict).sorted {$0.1 < $1.1}) {
        let value = "[\"\(k)\": \"\(v)\"]"
        println(value)
    }

哪个有效,但后来我不知道如何创建 value 的新词典。

什么是最好的解决方案?如何使其有效?

6 个答案:

答案 0 :(得分:19)

上面sorted函数的输出是数组。所以你不能得到钥匙和钥匙像字典这样的值。但是您可以使用map函数来检索那些已排序的键和&amp;值

  

返回一个包含source {根}的已排序元素的数组。   排序算法不稳定(可以改变相对顺序)   isOrderedBefore的元素不建立订单。)

let codeValueDict = ["us": "$", "it": "€", "fr": "€"]

let sortedArray = sorted(codeValueDict, {$0.0 < $1.0})
print(sortedArray)

let keys = sortedArray.map {return $0.0 }
print(keys)

let values = sortedArray.map {return $0.1 }
print(values)

答案 1 :(得分:6)

不订购字典。如果你想按顺序对它们进行枚举,你可以使用@ HoaParis的解决方案(这是我的偏好),或者

for (k,v) in sorted(codiceNomeDict, {$0.1 < $1.1}) { ... }

这比以前做的好一点,因为它不会生成临时数组。

但是如果你真的想要&#34;一个集合将一个值映射到另一个值并按其键排序&#34;那么你需要为此创建一些其他数据结构。所以,让我们这样做。这是一次很好的学习经历。

这个版本只是实现了SequenceType并提供了一个get / set下标,这是你通常想要的大部分内容。让它成为一个完整的CollectionType我觉得有点痛苦,因为startIndexendIndex都是O(1)。可能;比我今天早上想做的更多。

请注意Key: Comparable的主要添加内容。这就是为什么Dictionary 无法订购的原因。你没有承诺可以对钥匙进行分类。通过添加该要求,我们可以。

struct SortedDictionary<Key: Hashable, Value where Key: Comparable>: SequenceType {
    private var dict: Dictionary<Key, Value>
    init(_ dict: Dictionary<Key, Value>) {
        self.dict = dict
    }
    func generate() -> GeneratorOf<(Key, Value)> {
        let values = Array(zip(self.dict.keys, self.dict.values))
            .sorted {$0.0 < $1.0 }
        return GeneratorOf(values.generate())
    }
    subscript(key: Key) -> Value? {
        get        { return self.dict[key] }
        set(value) { self.dict[key] = value }
    }
}

var codeValueDict = ["us": "$", "it": "€", "fr": "€"]
var sortedDict = SortedDictionary(codeValueDict)
for (k, v) in sortedDict {
    println("\(k) => \(v)")
}
sortedDict["us"]
sortedDict["ab"] = "!"
sortedDict

为什么当你已经拥有SortedDictionary时,你会为sorted()而烦恼?嗯,通常我不会。但它确实提供了抽象的机会。您可以在创建对象时控制排序顺序,而不是在对象枚举时控制排序顺序。你可能会缓存排序顺序(虽然我怀疑在大多数情况下这会伤害而不是帮助)。

但我建议一般只使用sorted

答案 2 :(得分:4)

Swift不包含排序字典类型,并且无法对字典进行排序。您可以通过执行以下操作添加一个向[(Key, Value)]提供排序的扩展程序:

extension Dictionary {

    func sort(isOrderedBefore: (Key, Key) -> Bool) -> [(Key, Value)] {
        var result: [(Key, Value)] = []
        let sortedKeys = keys.array.sorted(isOrderedBefore)
        for key in sortedKeys {
            result.append(key, self[key]!)
        }
        return result
    }
}

答案 3 :(得分:3)

您无法以这种简单的方式对字典进行排序。我认为字典使用某种树数据结构。但是在排序之后你得到了一系列元组。所以你可以这样得到钥匙:

$productArr = array("Dell Inspiron 15 3521 Laptop CDC/ 2GB/ 500GB/ Linux Black Matte Textured Finish","Dell Inspiron 15 3521 Laptop CDC/ 4GB/ 500GB/ Win8 Black","Nikon D90 DSLR (Black) with AF-S 18-105mm VR Kit Lens");

答案 4 :(得分:3)

按字典的值对键进行排序实际上比最初看起来更简单:

let yourDict = ["One": "X", "Two": "B", "Three": "Z", "Four": "A"]
let sortedKeys = yourDict.keys.sort({ (firstKey, secondKey) -> Bool in
    return yourDict[firstKey] < yourDict[secondKey]
})

就是这样!真的没有什么了。

答案 5 :(得分:0)

在Swift 2

中排序键不区分大小写

这是一个函数,它返回一个不区分大小写的排序的键数组(或任何String值)。

请记住,Swift的字典数据结构不能按内存中的键排序存储。所以是的,您可以按键对其进行排序,但如果您打印它,那么键顺序也是随机的。

 /// returns an array of values sorted by values case-insensitive
func sortCaseInsensitive(values:[String]) -> [String]{

    let sortedValues = values.sort({ (value1, value2) -> Bool in

        if (value1.lowercaseString < value2.lowercaseString) {
            return true
        } else {
            return false
        }
    })
    return sortedValues
}

使用

进行通话
    let dict = ["world": "Hello!", "foo": "bar", "zYeah": "a", "akey": "xval"]
    let sortedKeys = sortCaseInsensitive(Array(dict.keys))