Reputation: 8391
The CollectionType
methods are all functional and the ones that return a collection all return an array.
Is it possible to create a generic function that implements a map
/ forEach
like function but has a return type of Self
?
extension CollectionType {
func otherMap(block: Generator.Element -> Generator.Element) -> Self {
var copy = self
copy.forEach {
$0 = block($0) // this obviously fails since $0 is immutable
}
return copy
}
}
Update :
Can this be unified? (func name says mutate even when it doesn't, I know ;))
extension Set {
func mutateCollection(block: Generator.Element -> Generator.Element) -> Set {
var copy : Set<Element> = []
for element in self {
copy.insert(block(element))
}
return copy
}
}
extension Dictionary {
func mutateCollection(block: Generator.Element -> Generator.Element) -> Dictionary {
var copy : [Key:Value] = [:]
for keyValuePair in self {
let key = keyValuePair.0
let value = keyValuePair.1
let blockResult = block(key, value)
copy[blockResult.0] = blockResult.1
}
return copy
}
}
extension Array {
func mutateCollection(block: Generator.Element -> Generator.Element) -> Array {
var copy : [Element] = []
for element in self {
copy.append(block(element))
}
return copy
}
}
Upvotes: 1
Views: 391
Reputation: 299355
There is no promise that an arbitrary CollectionType
can be instantiated or copied. So there's no way to implement your extension. A good way to see this is to try to implement this for FlattenCollection
or LazyCollection
. Or try creating a RandomValueCollection
and then try to implement this method.
But you're free to do this on a RangeReplaceableCollectionType
, which makes all the promises you need:
extension RangeReplaceableCollectionType {
func otherMap(block: Generator.Element -> Generator.Element) -> Self {
var copy = Self.dynamicType.init()
self.forEach {
copy.append(block($0))
}
return copy
}
}
Not all collections conform to RangeReplaceableCollectionType
. There probably is a good reason Set
doesn't, so you may have to create a simpler protocol of your own.
Remember, a CollectionType
may represent some static thing that isn't meaningful or safe to copy. For example, I might make a CollectionType
that represents "the files on this disk." Copying it could invalidate invariants (such as assumptions about caches and file pointers). There's no promise that a CollectionType
is a value type. It is free to be a reference.
Upvotes: 1