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
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))
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)
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 }
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.
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.
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
}
}