繁体   English   中英

所有元素都是相同类型的数组,使元素符合某种协议

[英]An array where all the element are the same type, make the element conforms to some protocol

我做了一个协议

protocol IndexConvertable{
    associatedtype T
    static func convertAnyTypeToInt(_ type: Self) -> Int
    static func convertIntToAnyType(_ int: Int) -> Self
}

该协议允许我索引具有无限双向值的类型,例如。 日期

例如。

extension Date: IndexConvertable{
    typealias T = Date
    
    static func convertAnyTypeToInt(_ date: Date) -> Int {
         date.convertDateToInt()
    }
    
    static func convertIntToAnyType(_ int: Int) -> Date {
         int.convertIntToDate()
    }
}

extension Date{
    /// This function converts a Date to an Int.
    func convertDateToInt(){
        ...
    }
}

extension Int{
    /// This function converts an Int to a Date.
    func convertIntToDate{
        ...
    }
}

从逻辑上讲,任何数组元素类型相同的数组都可以通过循环给定值转换为双向无限序列。

示例 1:

let colors: [Color] = [.red, .blue, .purple]

goal => [... .red, .blue, .purple, .red, .blue, .purple ...]

示例 2:

struct ColorView: View{
    let color: Color
    var body: some View{
        color.ignoreSafeArea()
    }
}

let colorViews: [ColorView] = [
    ColorView(color: .red),
    ColorView(color: .blue),
    ColorView(color: .purple)
]

=> [... ColorView(color: .red), ColorView(color: .blue), ColorView(color: .purple), ColorView(color: .red), ColorView(color: .blue), ColorView(color: .purple) ...]

转换计算:

let c: [Color] = [.red, .blue, .purple]

X -5 -4 -3 -2 -1 0 1个 2个 3个 4个 5个
c[y] c[1] c[2] c[0] c[1] c[2] c[0] c[1] c[2] c[0] c[1] c[2]
。蓝色的 。紫色的 。红色的 。蓝色的 。紫色的 。红色的 。蓝色的 。紫色的 。红色的 。蓝色的 。紫色的
let count = c.count

//Formula
y = { //if x is positive
    if x >= 0{
        x % count
    }else{ //if x is negative
        ((x % count) + count) % count
    }
}()

即使长度不同,该公式也适用于数组。

任何数组元素类型相同的数组,都可以通过循环给定的值来转换为双向无限序列。

我不想为每个可以包含在数组中的类型编写扩展。

我怎样才能满足要求? 或者任何达到相同目标的方法都是受欢迎的。

你有两个不相关的问题。 这是第二个的答案:

算法提供cycled . 如果这不符合你的需要,

public extension Collection {
  /// Circularly wraps `index`, to always provide an element,
  /// even when `index` is not valid.
  subscript(modulo index: Index) -> Element {
    self[
      self.index(
        startIndex,
        offsetBy:
          distance(from: startIndex, to: index)
          .modulo(count)
      )
    ]
  }
public extension BinaryInteger {
  func modulo(_ divisor: Self) -> Self {
    (self % divisor + divisor) % divisor
  }
}
[0, 1][modulo: -1] // 1
[0, 1][modulo: 2] // 0

您可以基于通用类型来限制扩展,因此您可以这样做

extension Collection where Index == Int {
    public subscript(index: Int, circular isCircular: Bool) -> Element {
        if !isCircular {
            return self[index]
        }
        
        let remainder = index % count
        let validIndex = remainder < Index.zero ? count + remainder : remainder
        return self[validIndex]
    }
}

使用示例

let numbers = [1, 2, 3, 4, 5]
numbers[-1, circular: true] // 5
numbers[6, circular: true] // 2
numbers[6] // out of bounds

let letters = ["a", "b", "c"]
letters[3, circular: true] // "a"

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM