首页 文章

在Swift中对字典进行排序

提问于
浏览
10

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

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

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

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

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

但我做不到 .

我试过这个

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

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

codesArray = sortedKeysAndValues.keys.array

给我错误'[(String, String)]'没有名为'keys'的成员,因为该解决方案不会返回完全字典 .

所以我试了另一个解决方案

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

哪个有效,但后来我不知道如何创建一个新的 Value 字典 .

什么是最好的解决方案?如何使其工作?

6 回答

  • 3

    上面 sorted 函数的输出是 Array . 因此,您无法获得像 Dictionary 这样的键和值 . 但是您可以使用 map 函数来检索那些已排序的键和值

    返回一个包含source 的已排序元素的Array . 排序算法不稳定(可以改变isOrderedBefore不 Build 顺序的元素的相对顺序) .

    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)
    
  • 2

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

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

    这比你之前做的更好一点,因为它不会生成临时数组 .

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

    这个版本只是实现 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
    

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

    但我建议一般只使用 sorted .

  • 19

    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
        }
    }
    
  • 2

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

    let codeValueDict = ["us": "$", "it": "€", "fr": "€"]
        let sortedKeysAndValues = sorted(codeValueDict) { $0.0 < $1.0 }
        let keys = sortedKeysAndValues.map {$0.0 }
        let values = sortedKeysAndValues.map {$0.1 }
    
  • 0

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

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

    就是这样!真的没什么了不起的 .

  • 6

    排序键在Swift 2中不区分大小写

    这是一个返回 case-insensitive 排序键数组(或任何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))
    

相关问题