数组 – 排序[Any]数组

数组 – 排序[Any]数组,第1张

概述给定一个定义如下的数组 let list: [Any] 我想把它分类 >其中的所有值都具有相同的Element类型 > AND元素是可比的. 当它应该返回排序的数组 所以我需要一个函数,当数组以如下的方式填充时 let list: [Any] = [10, 11, 0, 2, -1]let list: [Any] = ["Red", "Green", "Blue"]let list: [Any 给定一个定义如下的数组
let List: [Any]

我想把它分类

>其中的所有值都具有相同的Element类型
> AND元素是可比的.

当它应该返回排序的数组

所以我需要一个函数,当数组以如下的方式填充时

let List: [Any] = [10,11,2,-1]let List: [Any] = ["Red","Green","Blue"]let List: [Any] = [true,false,true,true]

确实返回排序的数组.

当它应该返回零

另一方面,当列表包含以下示例之一时

let List: [Any] = [CGPointZero,CGPoint(x:1,y:1)] // CGPoint is not comparablelet List: [Any] = [10,"Hello"] // Values of different types

我想要nil作为返回值.

任何想法?

编译时间解决方案
extension _ArrayType where Generator.Element == Any {    func sortQ() -> Any? {        return nil    }}extension _ArrayType where Generator.Element: Comparable {    func sortQ() -> [Self.Generator.Element] {        return self.sort(<)    }}// Because Bool is not comparable by default...extension Bool: Comparable {}public func < (lhs: Bool,rhs: Bool) -> Bool {    return !lhs && rhs // or Int(lhs) < Int(rhs)}[10,-1].sortQ()               //[-1,10,11]["Red","Blue"].sortQ()         //["Blue","Red"][true,true].sortQ()        //[false,true][CGPointZero,y:1)].sortQ() //nil[10,"Hello"].sortQ()                    //nil

运行时解决方案:

UPDATE

这是非最终状态.问题是与铸造相当. IMHO是不可能的.到目前为止,我不知道可选类型的技巧.无论如何,即使是转换元类型也是不可能的,因为类型在运行时才是不知道的.我的弱化解决方案是列出支持的可比类型:

extension _ArrayType {    func sortQ() -> [Generator.Element]? {        var arrayOK = true        let sortedArray = sort { (firstElement,secondElement) -> Bool in            guard arrayOK else {                return false            }            let f = Mirror(reflecting: firstElement)            let s = Mirror(reflecting: secondElement)            guard f.subjectType == s.subjectType else {                arrayOK = false                return false            }            switch String(f.subjectType) {            case "Int":                return (firstElement as! Int) < (secondElement as! Int)            case "String":                return (firstElement as! String) < (secondElement as! String)            case "Bool":                return (firstElement as! Bool) < (secondElement as! Bool)            default:                arrayOK = false                return false            }        }        return arrayOK ? sortedArray : nil    }}

更新2

第二个选项是使可比较的协议定义不同(AnyComparable).不幸的是,这意味着创建所有可比较类型的扩展.
否则没有办法,在编译时,编译器可以找到正确的函数/运算符(因为它不提前知道类型).

所以你有两个选择:

>如果你有一些想要比较和定义的类型
他们明确(更新1).
>使用不使用Self的界面
类型(更新2).

IMHO没有其他的解决方案

protocol AnyComparable {    func compareto(second: Any) -> Bool }extension AnyComparable where Self: Comparable {    func compareto(second: Any) -> Bool {        if let secondSameType = second as? Self {            return self < secondSameType        }        return false    }}extension Int: AnyComparable {}extension String: AnyComparable {}extension Bool: AnyComparable {}extension _ArrayType {    func sortQ() -> [Generator.Element]? {        var arrayOK = true        var wantedType: Any.Type?        let sortedArray = sort { (firstElement,secondElement) -> Bool in            guard arrayOK else {                return false            }            if wantedType == nil {                wantedType = Mirror(reflecting: firstElement).subjectType            }            guard let f = firstElement as? AnyComparable where wantedType == Mirror(reflecting: secondElement).subjectType else {                arrayOK = false                return false            }            return f.compareto(secondElement)        }        return arrayOK ? sortedArray : nil    }}
总结

以上是内存溢出为你收集整理的数组 – 排序[Any]数组全部内容,希望文章能够帮你解决数组 – 排序[Any]数组所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1040102.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-24
下一篇2022-05-24

发表评论

登录后才能评论

评论列表(0条)

    保存