Я составил протокол
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]
let count = c.count
//Formula
y = { //if x is positive
if x >= 0{
x % count
}else{ //if x is negative
((x % count) + count) % count
}
}()
Формула применяется к массиву, даже если длина отличается.
Любой массив, в котором тип элемента массива одинаков, может быть преобразован в двунаправленную бесконечную последовательность путем зацикливания заданных значений.
Я не хочу писать расширения для каждого типа, который может быть включен в массив.
Как я могу выполнить требования? Или любой метод достижения той же цели приветствуется.
Что T делает в вашем протоколе? Кажется, вы его нигде не используете. Действительно ли IndexConvertable связан с вашим вопросом? Вы, похоже, тоже не нуждаетесь и не используете его.
Вы можете ограничить расширение на основе универсального типа, чтобы вы могли сделать что-то вроде этого
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"
У вас два несвязанных вопроса. Это ответ для второго:
Алгоритмы предложений зациклены. Если это не соответствует вашим потребностям,
public extension Collection {
/// Circularly wraps `index`, to always provide an element,
/// even when `index` is not valid.
subscript(cycling index: Index) -> Element {
self[cycledIndex(index)]
}
/// Circularly wraps the result, to always provide an element.
func cycledIndex(_ index: Index, offsetBy distance: Int = 0) -> Index {
self.index(
startIndex,
offsetBy:
(self.distance(from: startIndex, to: index) + distance)
.modulo(count)
)
}
public extension BinaryInteger {
func modulo(_ divisor: Self) -> Self {
(self % divisor + divisor) % divisor
}
}
[0, 1][modulo: -1] // 1
[0, 1][modulo: 2] // 0
Тут как минимум два вопроса. Пожалуйста, разделите их!