swift 一个数组,其中所有元素都是相同类型,使元素符合某种协议

z31licg0  于 2023-01-12  发布在  Swift
关注(0)|答案(2)|浏览(125)

我制定了一个协议

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

协议允许我索引一个具有无限双向值的类型,例如Date
例如

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

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

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

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

例二:

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人|无|1个|第二章|三个|四个|五个|
| - ------|- ------|- ------|- ------|- ------|- ------|- ------|- ------|- ------|- ------|- ------|- ------|
| 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
    }
}()

该公式适用于长度不同的数组。
任何数组元素类型相同的数组,都可以通过循环给定的值转换为双向无穷序列。
我不想为数组中包含的每一个类型编写扩展。
我怎样才能达到要求?或者任何达到同样目的的方法都是受欢迎的.

2j4z5cfb

2j4z5cfb1#

你有两个不相关的问题。这是第二个问题的答案:
Algorithms提供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
izkcnapc

izkcnapc2#

您可以基于泛型类型约束扩展,因此可以执行如下操作

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"

相关问题