数组 – 排序[Any]数组

前端之家收集整理的这篇文章主要介绍了数组 – 排序[Any]数组前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
给定一个定义如下的数组
  1. let list: [Any]

我想把它分类

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

当它应该返回排序的数组

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

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

确实返回排序的数组.

当它应该返回零

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

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

我想要nil作为返回值.

任何想法?

编译时间解决方
  1. extension _ArrayType where Generator.Element == Any {
  2. func sortQ() -> Any? {
  3. return nil
  4. }
  5. }
  6.  
  7. extension _ArrayType where Generator.Element: Comparable {
  8. func sortQ() -> [Self.Generator.Element] {
  9. return self.sort(<)
  10. }
  11. }
  12.  
  13. // Because Bool is not comparable by default...
  14. extension Bool: Comparable {
  15. }
  16.  
  17. public func < (lhs: Bool,rhs: Bool) -> Bool {
  18. return !lhs && rhs // or Int(lhs) < Int(rhs)
  19. }
  20.  
  21. [10,-1].sortQ() //[-1,10,11]
  22. ["Red","Blue"].sortQ() //["Blue","Red"]
  23. [true,true].sortQ() //[false,true]
  24. [CGPointZero,y:1)].sortQ() //nil
  25. [10,"Hello"].sortQ() //nil

运行时解决方案:

UPDATE

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

  1. extension _ArrayType {
  2.  
  3. func sortQ() -> [Generator.Element]? {
  4. var arrayOK = true
  5. let sortedArray = sort { (firstElement,secondElement) -> Bool in
  6. guard arrayOK else {
  7. return false
  8. }
  9.  
  10. let f = Mirror(reflecting: firstElement)
  11. let s = Mirror(reflecting: secondElement)
  12.  
  13. guard f.subjectType == s.subjectType else {
  14. arrayOK = false
  15. return false
  16. }
  17.  
  18. switch String(f.subjectType) {
  19. case "Int":
  20. return (firstElement as! Int) < (secondElement as! Int)
  21. case "String":
  22. return (firstElement as! String) < (secondElement as! String)
  23. case "Bool":
  24. return (firstElement as! Bool) < (secondElement as! Bool)
  25. default:
  26. arrayOK = false
  27. return false
  28. }
  29. }
  30. return arrayOK ? sortedArray : nil
  31. }
  32. }

更新2

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

所以你有两个选择:

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

IMHO没有其他的解决方

  1. protocol AnyComparable {
  2. func compareTo(second: Any) -> Bool
  3. }
  4.  
  5. extension AnyComparable where Self: Comparable {
  6. func compareTo(second: Any) -> Bool {
  7. if let secondSameType = second as? Self {
  8. return self < secondSameType
  9. }
  10.  
  11. return false
  12. }
  13. }
  14.  
  15. extension Int: AnyComparable {
  16. }
  17.  
  18. extension String: AnyComparable {
  19. }
  20.  
  21. extension Bool: AnyComparable {
  22. }
  23.  
  24. extension _ArrayType {
  25.  
  26. func sortQ() -> [Generator.Element]? {
  27.  
  28. var arrayOK = true
  29. var wantedType: Any.Type?
  30.  
  31. let sortedArray = sort { (firstElement,secondElement) -> Bool in
  32. guard arrayOK else {
  33. return false
  34. }
  35.  
  36. if wantedType == nil {
  37. wantedType = Mirror(reflecting: firstElement).subjectType
  38. }
  39.  
  40. guard let f = firstElement as? AnyComparable where wantedType == Mirror(reflecting: secondElement).subjectType else {
  41. arrayOK = false
  42. return false
  43. }
  44.  
  45. return f.compareTo(secondElement)
  46. }
  47. return arrayOK ? sortedArray : nil
  48. }
  49. }

猜你在找的Swift相关文章