Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get column from 2D array – how to restrict array type in extension?

Tags:

arrays

swift

I'd like to extend Array in Swift to return a single element in each array, or column, for a 2D array. So far I have:

extension Array where // what goes here?
    func getColumn( column: Int ) -> [ Int ] {
        return self.map { $0[ column ] }
    }
}

I believe that I need to somehow specify a 2D array after where, but I have been unable to figure out the correct way to do that.

What is the correct syntax for specifying a 2D array after the where?

I'm also curious if there is a good documentation for how to specify what is available for after where in an extension lives. I couldn't find that at Apple's Swift extension documentation

Thanks in advance.

like image 636
Dribbler Avatar asked Feb 06 '16 18:02

Dribbler


People also ask

How do you pass a column of a 2D array to a function?

We can pass the 2D array as an argument to the function in C in two ways; by passing the entire array as an argument, or passing the array as a dynamic pointer to the function.

How do you store elements in a 2D array?

To declare a 2D array, specify the type of elements that will be stored in the array, then ( [][] ) to show that it is a 2D array of that type, then at least one space, and then a name for the array. Note that the declarations below just name the variable and say what type of array it will reference.

How do you initialize all elements of an 2D array to 0 in C++?

int array [ROW][COLUMN] = {0}; which means: "initialize the very first column in the first row to 0, and all other items as if they had static storage duration, ie set them to zero." int array [ROW][COLUMN] = {1}; it means "initialize the very first column in the first row to 1 and set all other items to zero".

Why it is necessary to give the column size in a 2D array initialization?

It is needed to compute the relative offset of the item you're actually accessing.


1 Answers

You need to constrain the Element type of the array. The subscript method is defined in the CollectionType protocol:

public protocol CollectionType : Indexable, SequenceType {
    // ...
    public subscript (position: Self.Index) -> Self.Generator.Element { get }
    // ...
}

Therefore you can define an extension method for arrays whose elements are collections:

extension Array where Element : CollectionType {
    func getColumn(column : Element.Index) -> [ Element.Generator.Element ] {
        return self.map { $0[ column ] }
    }
}

Example:

let a = [[1, 2, 3], [4, 5, 6]]
let c = a.getColumn(1)

print(c) // [2, 5]

You could even define it as an additional subscripting method:

extension Array where Element : CollectionType {
    subscript(column column : Element.Index) -> [ Element.Generator.Element ] {
        return map { $0[ column ] }
    }
}

let a = [["a", "b", "c"], [ "d", "e", "f" ]]
let c = a[column: 2]
print(c) // ["c", "f"]

Update for Swift 3:

extension Array where Element : Collection {
    func getColumn(column : Element.Index) -> [ Element.Iterator.Element ] {
        return self.map { $0[ column ] }
    }
}

or as subscript:

extension Array where Element : Collection {
    subscript(column column : Element.Index) -> [ Element.Iterator.Element ] {
        return map { $0[ column ] }
    }
}
like image 121
Martin R Avatar answered Sep 27 '22 17:09

Martin R