Sort a Dictionary in Swift

前端 未结 6 1045
情歌与酒
情歌与酒 2020-12-09 11:33

I know that this topic has been already discussed but I can\'t solve looking other answers, so sorry in advance for my ripetion!

I need to sort this Dictionary by ke

相关标签:
6条回答
  • 2020-12-09 11:59

    Sort keys case-insensitive in Swift 2

    Here is a function which returns a case-insensitive sorted array of keys (or any String values).

    Please keep in mind that Swift’s dictionary data structure can not be stored sorted by keys in memory. So yes, you can sort it by keys but if you print it for example then the key order is again random.

     /// 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
    }
    

    Call with

        let dict = ["world": "Hello!", "foo": "bar", "zYeah": "a", "akey": "xval"]
        let sortedKeys = sortCaseInsensitive(Array(dict.keys))
    
    0 讨论(0)
  • 2020-12-09 12:03

    The output of sorted function above is an Array. So you cannot get keys & values like a Dictionary. But you can use map function to retrieve those sorted keys & values

    Return an Array containing the sorted elements of source{according}. The sorting algorithm is not stable (can change the relative order of elements for which isOrderedBefore does not establish an order).

    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)
    
    0 讨论(0)
  • 2020-12-09 12:10

    You can't sort dictionary in such easy way. I think dictionary is using some sort of tree data structure. But after sorting you get an array of tuples. So you can get keys in such way:

        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 讨论(0)
  • 2020-12-09 12:11

    Sorting your keys by the dictionary's value is actually simpler than it appears at first:

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

    And that's it! There's really nothing more to it.

    0 讨论(0)
  • 2020-12-09 12:13

    Dictionaries are not ordered. If you want to enumerate over them in order, you can do that using @HoaParis's solution (which is my preference), or also

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

    which is just a little better way than what you were doing before because it doesn't generate a temporary array.

    But if you really want "a collection that maps one value to another and is ordered by its key" then you need to create some other data structure for that. So let's do that. It's a good learning experience.

    This version just implements SequenceType and provides a get/set subscript, which is most of what you'd generally want. Making it a full CollectionType is a bit of a pain I think, since startIndex and endIndex hae to be O(1). Possible; just more than I want to do this morning.

    Note the major addition of Key: Comparable. That's why Dictionary can't be ordered. There's no promise that you can sort their keys. By adding that requirement, we can.

    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
    

    Why would you bother with SortedDictionary when you already have sorted()? Well, usually I wouldn't. But it does offer opportunities for abstraction. You could control sort order at object creation rather than at object enumeration. You could potentially cache the sort order (though I suspect in most cases that will hurt rather than help).

    But I recommend just using sorted in general.

    0 讨论(0)
  • 2020-12-09 12:16

    Swift doesn't include a sorted dictionary type, and dictionaries cannot be sorted. You could add an extension that offers sorting to [(Key, Value)] by doing this:

    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
        }
    }
    
    0 讨论(0)
提交回复
热议问题