I would like to give my STACK struct the function contains(element: Element) that returns a bool as to whether var contents contains the element provided.
struct Stack<T>: SequenceType, Equatable, Printable, DebugPrintable {
typealias Element = T
private var contents: [Element]
var top: Int
init(arrayLiteral elements: T...) {
self.init(elements) }
// easier initialization
init<S: SequenceType where S.Generator.Element == Element>(_ sequence: S) {
self.contents = [Element]()
Swift.map(sequence) {self.contents[$0] = true }
}
// returns TRUE if the Stack contains <T> 'element'
func contains(element: Element) -> Bool {
return contents.filter(element != nil) ?? false
}
I would like to be able to define a new STACK and search its contents like so:
var newStack: Stack = [5, 23, 45, 100]
newStack.contains(45) // returns TRUE
Currently the compiler gives an error of:
"Cannot invoke '??' with an argument list of type '(Array, BooleanLiteralConvertible)' "
First of all, the generic element type T
must conform to Equatable
so that
you can compare the given element with the array elements using ==
:
struct Stack<T : Equatable> : YourProtocols... {
The filter
methods takes a closure which tests each array element:
let filtered = contents.filter({ $0 == element})
and returns a new array containing only the elements for which the test (the "predicate")
yields true
. But you don't need a new array, you want to test only for membership,
and that can be done with the Swift contains()
function:
func contains(element: Element) -> Bool {
return Swift.contains(contents, element)
}
Btw, your init
method does not compile. It seems to be copied from a different
collection type where the elements are stored in a dictionary. Here you can simply
use that an array can be initialized with a sequence:
init<S: SequenceType where S.Generator.Element == Element>(_ sequence: S) {
self.contents = Array(sequence)
}