按Swift中的值排序字典

Nik*_*ive 26 swift

是否有模拟 - (NSArray*)keysSortedByValueUsingSelector:(SEL)比较器在swift中?

如何在不转换为NSDictionary的情况下执行此操作?

我试过这个,但似乎不是一个好的解决方案.

var values = Array(dict.values)
values.sort({
    $0 > $1
    })

for number in values {
    for (key, value) in dict {
        if value == number {
            println(key + " : \(value)");
            dict.removeValueForKey(key);
            break
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

例:

var dict = ["cola" : 10, "fanta" : 12, "sprite" : 8]
dict.sortedKeysByValues(>) // fanta (12), cola(10), sprite(8)
Run Code Online (Sandbox Code Playgroud)

S.S*_*S.D 34

只需一行代码就可以按Swift 4中的值对字典进行排序:

    let sortedByValueDictionary = myDictionary.sorted { $0.1 < $1.1 }
Run Code Online (Sandbox Code Playgroud)

  • @JohnHarrington:尝试解释一下:“$0”和“$1”是用于定义比较函数的“两个伪条目”(然后由“sorted”函数将其应用于字典的所有条目)。由于我们要按值进行比较,因此必须使用第二个元素(0 是键,1 是值),因此是“.1”。(所以你也可以写 `{ $0.value &lt; $1.value }`。) (3认同)
  • 它在 Swift 4.1 中使用 Dictionary&lt;String, Int&gt; 对我有用 (2认同)
  • 注意,返回一个元组数组“(key, value)”,因此如果您想要对象,则需要像这样读取内容:“array[x].1” (2认同)

Dav*_*rry 21

尝试:

let dict = ["a":1, "c":3, "b":2]

extension Dictionary {
    func sortedKeys(isOrderedBefore:(Key,Key) -> Bool) -> [Key] {
        return Array(self.keys).sort(isOrderedBefore)
    }

    // Slower because of a lot of lookups, but probably takes less memory (this is equivalent to Pascals answer in an generic extension)
    func sortedKeysByValue(isOrderedBefore:(Value, Value) -> Bool) -> [Key] {
        return sortedKeys {
            isOrderedBefore(self[$0]!, self[$1]!)
        }
    }

    // Faster because of no lookups, may take more memory because of duplicating contents
    func keysSortedByValue(isOrderedBefore:(Value, Value) -> Bool) -> [Key] {
        return Array(self)
            .sort() {
                let (_, lv) = $0
                let (_, rv) = $1
                return isOrderedBefore(lv, rv)
            }
            .map {
                let (k, _) = $0
                return k
            }
    }
}

dict.keysSortedByValue(<)
dict.keysSortedByValue(>)
Run Code Online (Sandbox Code Playgroud)

更新:

更新为新的数组语法并从beta 3中排序语义.请注意,我正在使用sort而不是sorted最小化数组复制.该代码可以做得更紧凑,通过查看早期版本,并取代sortsorted和固定的KeyType[][KeyType]

更新到Swift 2.2:

更改类型从KeyTypeKeyValueTypeValue.使用new sortbuiltin Array代替sort(Array) Note所有这些的性能可以通过使用sortInPlace而不是使用来略微改进sort

  • 上面的代码在Xcode 6 Beta5中给出了错误:"使用未声明的类型'KeyType'"如果我通过Int更改所有KeyType/ValueType,编译器会说:"'Key'不是'Int'的子类型"和" 'Key'与第一个"func SortedKeys ..."中的'Int'不完全相同.Xcode6 Beta5的任何想法或修复? (2认同)

Log*_*gan 21

你可以使用这样的东西:

var dict = ["cola" : 10, "fanta" : 12, "sprite" : 8]

var myArr = Array(dict.keys)
var sortedKeys = sort(myArr) {
    var obj1 = dict[$0] // get ob associated w/ key 1
    var obj2 = dict[$1] // get ob associated w/ key 2
    return obj1 > obj2
}

myArr // ["fanta", "cola", "sprite"]
Run Code Online (Sandbox Code Playgroud)

  • `sort(myArr)`,在Swift 4中不再存在sort. (6认同)
  • 使用 myArr.sorted() 快速 4 (2认同)

pul*_*ife 16

这应该给你基于值的排序键,并且更清洁一点:

var sortedKeys = Array(dict.keys).sorted({dict[$0] < dict[$1]})
Run Code Online (Sandbox Code Playgroud)

  • 请考虑在您的答案中添加解释,仅代码答案不被认为是好的。 (2认同)

jeo*_*cha 9

我认为这是按值排序Swift字典的最简单方法.

let dict = ["apple":1, "cake":3, "banana":2]

let byValue = {
    (elem1:(key: String, val: Int), elem2:(key: String, val: Int))->Bool in
    if elem1.val < elem2.val {
        return true
    } else {
        return false
    }
}
let sortedDict = dict.sort(byValue)
Run Code Online (Sandbox Code Playgroud)


小智 5

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

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

就是这样!真的没什么了不起的.我还没有找到一种更快捷的方法.


Ash*_*Ash 5

很多答案,这是一个单行.我喜欢它,因为它充分利用了原生的Swift迭代函数,并且不使用变量.这应该有助于优化者发挥其魔力.

return dictionary.keys.sort({ $0 < $1 }).flatMap({ dictionary[$0] })
Run Code Online (Sandbox Code Playgroud)

请注意flatMap的使用,因为下载字典会返回一个可选值.在实践中,这应该永远不会返回nil,因为我们从字典本身获取密钥.flatMap只是为了确保结果不是一个选项数组.如果您的数组的关联值应该是可选的,则可以使用map.


eon*_*ist 5

OneLiner:

let dict = ["b":2,"a":1,"c":3]
(Array(dict).sorted{$0.1 < $1.1}).forEach{(k,v) in print("\(k):\(v)")}
//Output: a:1, b:2, c:3
Run Code Online (Sandbox Code Playgroud)

.forEach.map->功能编程交换

语法糖:

extension Dictionary where Value:Comparable {
    var sortedByValue:[(Key,Value)] {return Array(self).sorted{$0.1 < $1.1}}
}
extension Dictionary where Key:Comparable {
    var sortedByKey:[(Key,Value)] {return Array(self).sorted{$0.0 < $1.0}}
}
["b":2,"a":1,"c":3].sortedByKey//a:1, b:2, c:3
["b":2,"a":1,"c":3].sortedByValue//a:1, b:2, c:3
Run Code Online (Sandbox Code Playgroud)

  • @vikingosegundo OK \ _(ツ)_ /¯ (2认同)

小智 5

如果您希望输出是按值排序的元组形式的键值对数组,以下内容可能很有用。

var dict = ["cola" : 10, "fanta" : 12, "sprite" : 8]
let sortedArrByValue = dict.sorted{$0.1 > $1.1}
print(sortedArrByValue) // output [(key: "fanta", value: 12), (key: "cola", value: 10), (key: "sprite", value: 8)]
Run Code Online (Sandbox Code Playgroud)


kel*_*lin 5

由于 Swift 3.0Dictionary具有sorted(by:)返回元组 ( [(Key, Value)])数组的函数。

let sorted = values.sorted(by: { (keyVal1, keyVal2) -> Bool in
    keyVal1.value > keyVal2.value
})
Run Code Online (Sandbox Code Playgroud)


小智 5

按键或值对字典进行排序

使用Swift 5.2内部处理“排序”:

var unsortedDict = ["cola" : 10, "fanta" : 12, "sprite" : 8]

// sorting by value
let sortedDictByValue = unsortedDict.sorted{ $0.value > $1.value } // from lowest to highest using ">"
print("sorted dict: \(sortedDictByValue)")
// result: "sorted dict: [(key: "fanta", value: 12), (key: "cola", value: 10), (key: "sprite", value: 8)]\n"

// highest value
print(sortedDictByValue.first!.key)  // result: fanta
print(sortedDictByValue.first!.value)  // result: 12
// lowest value
print(sortedDictByValue.last!.key)  // result: sprite
print(sortedDictByValue.last!.value)  // result: 8
// by index
print(sortedDictByValue[1].key)  // result: cola
print(sortedDictByValue[1].value)  // result: 10

// sorting by key
let sortedDictByKey = unsortedDict.sorted{ $0.key < $1.key } // in alphabetical order use "<"
// alternative:
// let sortedDictByKey = unsortedDict.sorted{ $0 < $1 }  // without ".key"
print("sorted dict: \(sortedDictByKey)")
// result: "sorted dict: [(key: "cola", value: 10), (key: "fanta", value: 12), (key: "sprite", value: 8)]\n"

// highest value
print(sortedDictByKey.first!.key)  // result: cola
print(sortedDictByKey.first!.value)  // result: 10
// lowest value
print(sortedDictByKey.last!.key)  // result: sprite
print(sortedDictByKey.last!.value)  // result: 8
// by index
print(sortedDictByKey[1].key)  // result: fanta
print(sortedDictByKey[1].value)  // result: 12
Run Code Online (Sandbox Code Playgroud)