排序[Any]数组 [英] Sorting the [Any] array

查看:205
本文介绍了排序[Any]数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定一个数组定义如下

  let list:[Any] 

我想对它进行排序


  1. 其中的所有值都具有相同的类型元素

  2. AND 元素可比较



应该返回排序后的数组

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

 让列表:[Any] = [10,11,0,2,-1] 
让列表:[Any] = [Red,Green ,Blue]
让列表:[Any] = [true,false,true,true]

确实返回了排序后的数组。



当它返回nil



另一方面,当 list 包含以下示例之一:

  let list:[Any] = [CGPointZero,CGPoint(x:1,y:1)] // CGPoint不可比
let list: [Any] = [10,Hello] //不同类型的值

我想<$

任何想法?

解决方案编译时间解决方案

 扩展名_ArrayType其中,Generator.Element = =任何{
func sortQ() - >任何? {
return nil
}
}

extension _ArrayType where Generator.Element:Comparable {
func sortQ() - > [Self.Generator.Element] {
return self.sort(<)
}
}

//因为Bool在默认情况下不具有可比性......
扩展Bool:可比较{
}

public func< (lhs:Bool,rhs:Bool) - > Bool {
return!lhs&& rhs //或Int(lhs)< Int(rhs)
}

[10,11,0,2,-1] .sortQ()// [ - 1,0,2,10,11] $ b $ sortQ()// [Blue,Green,Red]
[true,false,true,true] .sortQ() // [false,true,true,true]
[CGPointZero,CGPoint(x:1,y:1)]。sortQ()// nil
[10,Hello]。sortQ )//无

运行时解决方案

更新



这是非最终状态。问题是与铸造相媲美。恕我直言,这是不可能的。到现在为止,我不知道关于可选类型的技巧。无论如何,即使是元类型的转换也是不可能的,因为直到运行时才知道类型。我的弱解决方法是列出支持的可比类型:

 扩展名_ArrayType {

func sortQ() - > [Generator.Element]? {
var arrayOK = true
let sortedArray = sort {(firstElement,secondElement) - > Bool in
guard arrayOK else {
return false
}

let f = Mirror(反射:firstElement)
let s = Mirror(反射:secondElement )

guard f.subjectType == s.subjectType else {
arrayOK = false
return false
}

switch String(f .subjectType){
caseInt:
return(firstElement as!Int)< (secondElement as!Int)
caseString:
return(firstElement as!String)< (secondElement as!String)
caseBool:
return(firstElement as!Bool)< (secondElement as!Bool)
default:
arrayOK = false
return false
}
}
return arrayOK? sortedArray:nil
}
}

UPDATE 2

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

<所以你有两种选择:如果你有一些你想要比较的类型,并明确定义
,你可以有两种选择:


  1. 更新1)。

  2. 使用不使用Self
    类型的接口(更新2)。

恕我直言,没有其他解决方案

  protocol AnyComparable {
func compareTo(second:任何) - > Bool
}

扩展AnyComparable where Self:Comparable {
func compareTo(second:Any) - >布尔{
如果让secondSameType =秒为? Self {
return self< secondSameType
}

返回false
}
}

扩展名Int:AnyComparable {
}

扩展字符串:AnyComparable {
}

扩展Bool:AnyComparable {
}

扩展_ArrayType {

func sortQ() - > [Generator.Element]? {

var arrayOK = true
var wantedType:Any.Type?

let sortedArray = sort {(firstElement,secondElement) - > Bool in
guard arrayOK else {
return false
}
$ b $如果wantedType == nil {
wantedType = Mirror(反射:firstElement).subjectType
}

后卫让f = firstElement为? AnyComparable where wantedType == Mirror(reflect:secondElement).subjectType else {
arrayOK = false
return false
}

return f.compareTo(secondElement)
}
return arrayOK? sortedArray:nil
}
}


Given an array defined as follow

let list: [Any]

I want to sort it WHEN

  1. all the values inside it have the same type Element
  2. AND Element is Comparable.

When it should return the sorted array

So I would need a function that when the array is populated in a way like the followings

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

does return the sorted array.

When it should return nil

On the other hand when list contains one of the following examples

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

I want nil as return value.

Any idea?

解决方案

Compile time solution

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, 11, 0, 2, -1].sortQ()               //[-1, 0, 2, 10, 11]
["Red", "Green", "Blue"].sortQ()         //["Blue", "Green", "Red"]
[true, false, true, true].sortQ()        //[false, true, true, true]
[CGPointZero, CGPoint(x:1, y:1)].sortQ() //nil
[10, "Hello"].sortQ()                    //nil

Runtime solutions:

UPDATE

Here is non final state. The problem is with casting to comparable. IMHO it is not possible. Until now I didn't know about trick with optional type. Anyway even casting of meta type is not possible because type is not known until runtime. My weak workaround is to list supported comparable types:

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

UPDATE 2

The second option is to have comparable protocol defined differently (AnyComparable). Unfortunately it means to create extensions for all Comparable types. Otherwise there's no way, at compile-time, the compiler can find the correct function/operator (as it doesn't know the types ahead of time).

So you have two options:

  1. if you had some idea of the types you were comparing and define them explicitly (update 1).
  2. Use interface which does not use Self type (update 2).

IMHO there is no other solution

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]数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆