我可以创建一个迭代器来创建前缀:
extension Array where Element == Int {
func prefixesInt() -> AnyIterator<[Element]> {
var length = 0
return AnyIterator {
guard length < self.count else { return nil }
length += 1
return Array(self.prefix(length))
}
}
}
for prefix in [1,10,5].prefixesInt() {
print(prefix) // Prints: [1] then [1, 10] then [1, 10, 5]
}
现在我想通过以下方式与其他类型实现相同的目标:
1) 将类型编码为 Int
2)使用相同的前缀函数
3)解码回原始类型
[我知道可能有其他方法可以实现这一点,但出于各种原因,我想遵循这条路线,也想了解更多。]
所以我需要:
extension Array where Element: Equatable {
func encode() -> [Int] {
return map { self.firstIndex(of: $0)! }
}
}
print(["A", "B", "A", "C"].encode()) // Prints: [0, 1, 0, 3]
extension Array where Element == Int {
func decode<Output>(_ original: [Output]) -> [Output] {
return map { original[$0] }
}
}
print([2,3,0].decode(["P", "Q", "R", "S"])) // Prints: ["R", "S", "P"]
我现在可以做我想做的事:
extension Array where Element: Equatable {
func prefixes() -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
return encode().prefixesInt().lazy.map { $0.decode(self) }
}
}
for prefix in ["H","A","T"].prefixes() {
print(prefix)
}
我现在想更进一步,将转换(在本例中为前缀)转换为参数,我的尝试是:
extension Array where Element: Equatable {
func encodeTransformDecode(transform: ([Int]) -> AnyIterator<[Int]> ) -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
return transform(encode()).lazy.map { $0.decode(self) }
}
}
编译得很好但是当我尝试时:
extension Array where Element: Equatable {
func prefixes2() -> LazyMapSequence<AnyIterator<[Element]>, [Element]> {
return encodeTransformDecode(transform: prefixesInt) //ERROR: 'Array<Element>' is not convertible to 'Array<Int>'
}
}
for prefix in ["A","B","C"].prefixes2() {
print(prefix)
}
然后我得到指示的错误
我被困住了。任何帮助表示赞赏。
全码:
print("========== prefixesInt")
extension Array where Element == Int {
func prefixesInt() -> AnyIterator<[Element]> {
var length = 0
return AnyIterator {
guard length < self.count else { return nil }
length += 1
return Array(self.prefix(length))
}
}
}
for prefix in [1,10,5].prefixesInt() {
print(prefix) // Prints: [1] then [1, 10] then [1, 10, 5]
}
print("============ encode")
extension Array where Element: Equatable {
func encode() -> [Int] {
return map { self.firstIndex(of: $0)! }
}
}
print(["A", "B", "A", "C"].encode()) // Prints: [0, 1, 0, 3]
print("============ decode")
extension Array where Element == Int {
func decode<Output>(_ original: [Output]) -> [Output] {
return map { original[$0] }
}
}
print([2,3,0].decode(["P", "Q", "R", "S"])) // Prints: ["R", "S", "P"]
print("============ prefixes")
extension Array where Element: Equatable {
func prefixes() -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
return encode().prefixesInt().lazy.map { $0.decode(self) }
}
}
for prefix in ["H","A","T"].prefixes() {
print(prefix)
}
extension Array where Element: Equatable {
func encodeTransformDecode(transform: ([Int]) -> AnyIterator<[Int]> ) -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
return transform(encode()).lazy.map { $0.decode(self) }
}
}
print("============ prefixes2")
extension Array where Element: Equatable {
func prefixes2() -> LazyMapSequence<AnyIterator<[Element]>, [Element]> {
return encodeTransformDecode(transform: prefixesInt)
}
}
for prefix in ["A","B","C"].prefixes2() {
print(prefix)
}
正如我的评论中所指出的,并且您已经在自己的答案中进行了探索,代码中的核心问题是您的类型prefixesInt
不正确。实例方法具有以下形式的类型:
(<object type>) -> (<argument types>) -> <return type>
传递的值<object type>
是self
函数中绑定的值。所以类型prefixesInt
是:
([Int]) -> () -> AnyIterator<[Int]>
要修复您的代码,您只需要更改prefixes2
:
func prefixes2() -> LazyMapSequence<AnyIterator<[Int]>, [Element]>
{
return encodeTransformDecode(transform: { $0.prefixesInt() } )
}
类型已更改为 includeAnyIterator<[Int]>
而不是AnyIterator<[Element]>
并且{ $0.prefixesInt() }
传递了一个闭包而不是仅仅传递prefixesInt
(前者将数组作为参数,而编译器将后者传递给 ,后者是 的简写self.prefixesInt
,作为具有self
pre-bound当前值的闭包- 即self
被Array<Equatable>
prefixes2
称为)。
HTH
要查看与您生成的代码的联系,请考虑:
<value>.method(<args>)
只是以下内容的简写:
<type of value>.method(<value>)(<args>)
在这种情况下,这意味着:
$0.prefixesInt()
是以下的简写:
Array<Int>.prefixesInt($0)()
这是你生产的,但分布在prefixes()
( Array<Int>.prefixesInt
) 和encodeTransformDecode
( transform(encode())()
) 之间。通过使用简写并传递闭包,不需要更改encodeTransformDecode
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句