Arrays 扩展数组以检查它是否在Swift中排序?
我想扩展数组类,这样它就可以知道它是否被排序(升序)。我想添加一个名为Arrays 扩展数组以检查它是否在Swift中排序?,arrays,swift,Arrays,Swift,我想扩展数组类,这样它就可以知道它是否被排序(升序)。我想添加一个名为isSorted的计算属性。如何声明数组的元素具有可比性 我目前在操场上的实施 extension Array { var isSorted: Bool { for i in 1..self.count { if self[i-1] > self[i] { return false } } return true } } // The way I want to get th
isSorted
的计算属性。如何声明数组的元素具有可比性
我目前在操场上的实施
extension Array {
var isSorted: Bool {
for i in 1..self.count {
if self[i-1] > self[i] { return false }
}
return true
}
}
// The way I want to get the computed property
[1, 1, 2, 3, 4, 5, 6, 7, 8].isSorted //= true
[2, 1, 3, 8, 5, 6, 7, 4, 8].isSorted //= false
错误找不到接受提供的参数的'>'的重载
当然,我仍然有一个错误,因为斯威夫特不知道如何比较元素。如何在Swift中实现此扩展?还是我做错了什么?您遇到了Swift泛型的问题,现在无法以您喜欢的方式解决(可能在未来的Swift版本中)。另见 目前,您需要定义一个函数(例如在全局范围内):
func排序(数组:数组)->Bool{
对于1..array[i]中的i{
返回错误
}
}
返回真值
}
设i=[1,2,3]
设j=[2,1,3]
设k=[UIView(),UIView()]
println(isSorted(i))//打印“true”
println(isSorted(j))//打印“false”
println(isSorted(k))//错误:调用中缺少参数#2的参数
IMHO,错误消息具有误导性,因为实际错误类似于“UIView不满足可比的类型约束”。自由函数的替代解决方案是执行Swift内置的
Array.sort
和Array.sorted
方法所做的操作,并要求将合适的比较器传递给该方法:
extension Array {
func isSorted(isOrderedBefore: (T, T) -> Bool) -> Bool {
for i in 1..<self.count {
if !isOrderedBefore(self[i-1], self[i]) {
return false
}
}
return true
}
}
[1, 5, 3].isSorted(<) // false
[1, 5, 10].isSorted(<) // true
[3.5, 2.1, -5.4].isSorted(>) // true
扩展数组{
函数排序(在:(T,T)->Bool)->Bool之前排序){
对于Swift 2.0中的i..,您现在可以扩展协议了
extension CollectionType where Generator.Element: Comparable {
public var isSorted: Bool {
var previousIndex = startIndex
var currentIndex = startIndex.successor()
while currentIndex != endIndex {
if self[previousIndex] > self[currentIndex] {
return false
}
previousIndex = currentIndex
currentIndex = currentIndex.successor()
}
return true
}
}
[1, 2, 3, 4].isSorted // true
["a", "b", "c", "e"].isSorted // true
["b", "a", "c", "e"].isSorted // false
[/* Anything not implementing `Comparable` */].isSorted // <~~ Type-error
Generator.Element所在的扩展集合类型:可比较{
公共变量分类:Bool{
var previousIndex=startIndex
var currentIndex=startIndex.successiver()
而currentIndex!=endIndex{
如果self[previousIndex]>self[currentIndex]{
返回错误
}
previousIndex=currentIndex
currentIndex=currentIndex.successiver()
}
返回真值
}
}
[1,2,3,4]。isSorted//true
[“a”、“b”、“c”、“e”]。isSorted//true
[“b”、“a”、“c”、“e”]。isSorted//false
[/*任何不实现“可比”*/].isSorted/对我来说,最灵活的解决方案是结合NSAddict和Wes Campave的答案。即,结合了能够扩展协议和将比较器函数作为参数传递的优势。这消除了仅将其用于数组和将其约束到符合Compariable
协议
extension CollectionType
{
func isSorted(isOrderedBefore: (Generator.Element, Generator.Element) -> Bool) -> Bool
{
var previousIndex = startIndex
var currentIndex = startIndex.successor()
while currentIndex != endIndex
{
if isOrderedBefore(self[previousIndex], self[currentIndex]) == false
{
return false
}
previousIndex = currentIndex
currentIndex = currentIndex.successor()
}
return true
}
}
这可以用于任何集合
类型,并且可以根据您的需要定义排序标准。
适应,这将在Swift 4中起作用
扩展数组,其中Iterator.Element:可比较{
func被排序(isOrderedBefore:(Iterator.Element,Iterator.Element)->Bool)->Bool{
对于1中的i..
实际上,您可以扩展序列
协议以获得更通用的解决方案:
扩展序列{
函数被排序(按递增顺序:(元素,元素)抛出->布尔)再抛出->布尔{
var iterator=makeIterator()
guard var previous=iterator.next()else{
//序列为空
返回真值
}
而让current=iterator.next(){
guard try areInIncreasingOrder(上一个,当前)else{
返回错误
}
先前=当前
}
返回真值
}
}
扩展序列,其中元素:可比较{
func isSorted()->Bool{
return isSorted(按:这里是Swift 4中的一个解决方案,当self.count
等于或小于1时不会崩溃:
extension Array where Element: Comparable {
func isSorted(by isOrderedBefore: (Element, Element) -> Bool) -> Bool {
for i in stride(from: 1, to: self.count, by: 1) {
if !isOrderedBefore(self[i-1], self[i]) {
return false
}
}
return true
}
}
此代码段假定已对包含1或0个元素的数组进行排序
在for循环范围中以1开头的原因是:如果self.count=)//true
[1,4,7].isSorted(由:{x,y in.)
返回x+2
如果您想要不带参数的简单函数,如Swift中的sort()或sorted():
extension Array where Element : Comparable {
func isSorted() -> Bool {
guard self.count > 1 else {
return true
}
for i in 1..<self.count {
if self[i-1] > self[i] {
return false
}
}
return true
}
}
扩展数组,其中元素:可比较{
func isSorted()->Bool{
防护自我计数>1其他{
返回真值
}
因为我在1..self[i]{
返回错误
}
}
返回真值
}
}
通用功能,可以为实现提供快捷方式
extension Collection where Element: Comparable {
var isSorted: Bool {
guard count > 1 else {
return true
}
let pairs = zip(prefix(count - 1), suffix(count - 1))
return !pairs.contains { previous, next in
previous > next
}
}
}
[0, 1, 1, 2].isSorted // true
[0, 2, 2, 1].isSorted // false
在Swift 4.2及更高版本中,您可以通过一些序列切片来拼凑:
扩展数组,其中元素:可比较{
func isascing()->Bool{
返回zip(self,self.dropFirst()).allsuccess(Bool{
返回zip(self,self.dropFirst()).allsuccess(>=)
}
}
@kAzec的答案似乎在元素相等时不起作用。这是因为根据定义,递增顺序(a,a)必须为false
以下方法应该可以很好地工作
扩展序列{
func被排序(按areInIncreasingOrder:(元素,元素)抛出->布尔)
后退->布尔{
var it=makeIterator()
guard var previous=it.next()else{return true}
而让current=it.next(){
如果尝试!正在递增顺序(上一个,当前)&&
areInIncreasingOrder(当前、以前){
返回错误
}
先前=当前
}
返回真值
}
}
扩展序列,其中元素:可比较{
func isSorted()->Bool{
返回排序(通过:总结前面的答案有一个最小的通用数组扩展要检查:
扩展数组{
func被排序(u谓词:(元素,元素)抛出->Bool)
[1, 2, 3].isSorted(by: >) // true
[3, 2, 2].isSorted(by: >=) // true
[1, 4, 7].isSorted(by: {x, y in
return x + 2 < y * y
}) // true
let a: [Int] = [1]
a.isSorted(by: <) // true
let b: [Int] = []
b.isSorted(by: >) // true
extension Array where Element : Comparable {
func isSorted() -> Bool {
guard self.count > 1 else {
return true
}
for i in 1..<self.count {
if self[i-1] > self[i] {
return false
}
}
return true
}
}
extension Collection where Element: Comparable {
var isSorted: Bool {
guard count > 1 else {
return true
}
let pairs = zip(prefix(count - 1), suffix(count - 1))
return !pairs.contains { previous, next in
previous > next
}
}
}
[0, 1, 1, 2].isSorted // true
[0, 2, 2, 1].isSorted // false