Reputation: 1574
How do I extend Array<Array>
in Swift?
extension Array where Element == Array { //This is where the error occurs
someMethod()
}
Furthermore, how would I extend an array of arrays of a specific type, for example:
extension Array where Element == Array<Int> { //Can I even do this?
someOtherMethod()
}
Thanks in advance for your help!
Upvotes: 5
Views: 1652
Reputation: 680
Solution for generic approach (Swift 5.5):
extension Collection where Element: Collection, Element.Element: Equatable, Element.Index == Int {
// Returns aggregated count of all elements.
func totalCount() -> Int {
return reduce(into: 0) { partialResult, innerCollection in
partialResult += innerCollection.count
}
}
// Returns `IndexPath` for given `element` inside 2d array.
func indexPath(for element: Element.Element) -> IndexPath? {
for (section, innerCollection) in enumerated() {
if let row = innerCollection.firstIndex(of: element) {
return IndexPath(row: row, section: section)
}
}
return nil
}
}
Upvotes: 0
Reputation: 152
Here's a start for someone wanting to do this more generically than the answers so far have shown.
Extending Array<Array>
:
protocol ExpressibleAsDouble { // for illustration
func asDouble() -> Double
}
extension Array where Element: Sequence, Element.Element: ExpressibleAsDouble {
func asDoubles() -> [[Double]] {
return self.map { row in
row.map { scalar in
scalar.asDouble()
}
}
}
}
//-------------------------------------------
//example usage
extension Int: ExpressibleAsDouble {
func asDouble() -> Double {
return Double(self)
}
}
let ints: [[Int]] = [[1, 2], [3, 4]]
print(ints.asDoubles())
// prints: [[1.0, 2.0], [3.0, 4.0]]
This is actually extending Array<any sequence, Array being one possible option>
, I'm not sure if you can constrict it to just Array<Array>
if you want to refer to the nested scalars generically.
Element
refers to the first dimension of the Array
(which is another Array), and Element.Element
refers to the type of the nested dimension (which are scalars if we're talking about a 2D array).
Upvotes: 0
Reputation: 15248
You can extend in either way
extension Array where Element == Int {
func someIntegers() {
}
}
extension Array where Element == Array<String> {
func someStrings() {
}
}
and call like this anywhere,
[0, 1, 2].someIntegers()
[["hi"]].someStrings()
Upvotes: 5
Reputation: 17863
I've used
extension Array where Element: RandomAccessCollection, Element.Index == Int {
}
e.g. to add custom subscripts by IndexPath
Upvotes: 2