有没有一种简单的方法可以根据数字的个数对数组进行排序?如果一个数字具有相同的计数,则将最大的数字放在第一位。
[2,8,2,6,1,8,2,6,6]
to
[6,6,6,2,2,2,8,8,1]
最佳答案
您正在寻找一种获取值频率的方法。
只要值是Hashable
,这个函数就可以工作:
它扩展了 Element
为 Hashable
的所有序列类型,因此 Int
数组将起作用。
extension SequenceType where Generator.Element : Hashable {
func frequencies() -> [Generator.Element:Int] {
var results : [Generator.Element:Int] = [:]
for element in self {
results[element] = (results[element] ?? 0) + 1
}
return results
}
}
然后你可以这样做:
let alpha = [2,8,2,6,1,8,2,6,6]
let sorted = alpha.frequencies().sort {
if $0.1 > $1.1 { // if the frequency is higher, return true
return true
} else if $0.1 == $1.1 { // if the frequency is equal
return $0.0 > $1.0 // return value is higher
} else {
return false // else return false
}
}
更好的是,您现在可以创建另一个序列类型扩展。
现在他们需要符合 Comparable
以及 Hashable
extension SequenceType where Generator.Element : protocol<Hashable,Comparable> {
func sortByFrequency() -> [Generator.Element] {
// the same sort function as before
let sorted = self.frequencies().sort {
if $0.1 > $1.1 {
return true
} else if $0.1 == $1.1 {
return $0.0 > $1.0
} else {
return false
}
}
// this is to convert back from the dictionary to an array
var sortedValues : [Generator.Element] = []
sorted.forEach { // for each time the value was found
for _ in 0..<$0.1 {
sortedValues.append($0.0) // append
}
}
return sortedValues
}
}
所有这些的最终用法将如下所示:
let sorted = alpha.sortByFrequency() // [6, 6, 6, 2, 2, 2, 8, 8, 1]
super 干净:)
如果你更喜欢一个更接近 sort
本身的函数,你也可以使用这个:
extension SequenceType where Generator.Element : Hashable {
func sortedFrequency(@noescape isOrderedBefore: ((Self.Generator.Element,Int), (Self.Generator.Element,Int)) -> Bool) -> [Generator.Element] {
let sorted = self.frequencies().sort {
return isOrderedBefore($0,$1) // this uses the closure to sort
}
var sortedValues : [Generator.Element] = []
sorted.forEach {
for _ in 0..<$0.1 {
sortedValues.append($0.0)
}
}
return sortedValues
}
}
上面的扩展在内部将数组转换为频率字典,只要求您输入一个返回 Bool
的 closure
。然后您可以根据需要应用不同的排序。
因为您将带有排序逻辑的闭包传递给此函数,所以 SequenceType
的 Elements
不再需要具有可比性。
所有速记的备忘单:
$0 // first element
$1 // second element
$0.0 // value of first element
$0.1 // frequency of first element
排序:
let sortedB = alpha.sortedFrequency {
if $0.1 > $1.1 {
return true
} else if $0.1 == $1.1 {
return $0.0 > $1.0
} else {
return false
}
} // [6, 6, 6, 2, 2, 2, 8, 8, 1]
关于arrays - 计算数组中的数字并按 swift 计数对它们进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34614782/