如何在 swift 中创建匿名列表,例如 Kotlin

how to create anonymous list in swift, such as Kotlin

当我将 kotlin 代码更改为 swift 代码时。我在创建抽象不可变列表时遇到问题。

private interface A{
    val Id : Int
    val anotherValue : Int
}

private val anotherList : ArrayList<A>

override val idList: List<Int>
    get() = object : AbstractList<Int>() {
        override val size: Int
            get() = anotherList.size

        override fun get(index: Int): Int {
            return anotherList[index].Id
        }
    }

此代码是在调用 'idList' 属性 时创建的 'AbstractList'。我打算不占用任何额外的容量,除了创建的实例自己的容量。

我尝试在 Swift 迁移代码如下:

override var idList: [Int]{
    return self.anotherList.map{
        [=12=].Id
    }
}

但是这段代码比较占内存,比如List Copy。我该怎么办?

您可以使用 lazy 地图:

let idList: LazyMapSequence<[A], Int> {
    self.anotherList.lazy.map(\.id)
}

我很确定 lazy 为您提供了数组的惰性“视图”。由于这是一个惰性序列,因此在您需要之前不会计算 ID。此外,由于数组是随机访问的,如果您需要第三个 ID,则不会计算第一个和第二个 ID。

或者,我认为这样更好,编写您自己的 ArrayKeyPathView 集合:

struct ArrayKeyPathView<WrappedElement, KeyPathType> : RandomAccessCollection {
    subscript(position: Int) -> Element {
        get {
            wrapped[position][keyPath: keyPath]
        }
    }
    
    var startIndex: Int {
        wrapped.startIndex
    }
    
    var endIndex: Int {
        wrapped.endIndex
    }
    
    
    var indices: Range<Int> {
        wrapped.indices
    }
    
    typealias Index = Int
    typealias SubSequence = ArrayKeyPathView
    typealias Element = KeyPathType
    typealias Indices = Range<Int>
    
    private let wrapped: [WrappedElement]
    private let keyPath: KeyPath<WrappedElement, KeyPathType>
    
    init(_ array: [WrappedElement], keyPath: KeyPath<WrappedElement, KeyPathType>) {
        self.wrapped = array
        self.keyPath = keyPath
    }
}

用法:

let idList: ArrayKeyPathView<A, Int> {
    ArrayKeyPathView(self.anotherList, keyPath: \.id)
}

由于 swift 数组是写时复制,仅将其传递给 ArrayKeyPathView 不会创建副本。